React state in parent or child components - javascript

I'm making a typeahead input using React and I'd like some input on where to place my state.
I'm only using React, and not some architecture like Redux or what have you
My root component looks like this:
import React, { Component } from 'react';
import InputSearch from './input_search';
import SearchHints from './search_hints';
class Main extends Component {
constructor(props) {
super(props)
this.state =
/* Some state here? */
}
}
render() {
return (
<InputSearch />
<SearchHints />
);
}
}
The InputSearch obviously takes care of the <input /> markup and SearchHints takes care of rendering a list of suggestions as the user types
My question is whether or not I should keep my state in the root component, or place it in the different child components
The state will contain logic for matching the user input to some data array of search suggestions, and also logic for updating the value from the a selected search hint into the input field. I feel like the logic between the two child components is kind of intermingled, which I why im unsure of where to place it.

You should always maintain your state in your root component because flow of your app revolves around your root component.So you should plan your components accordingly.
In case you feel that maintaining state of your app in root is difficult and your sub components also need to maintain some local state then you should use stores(flux,redux).
Now looking at your problem statement keeping your state at root will be a simple solution as you can just pass your state to child components and do any computations you want to do in child components.Maintaining different states for each child component will make your code more complex.
To achieve this just set your state like something
{input:""}
in your inputsearch component you can do
function:method(event)
{
this.props.setInput(event)
}
<input type="text" onChange={this.setInput}/>
In your main root component
function:setInputAsState(input)
{
this.setState({
input:input
])
}
<inputsearch setInput={this.setInputAsState}/>
<SearchHints state={this.state.input}/>
Now compute anything you want in SearchHints component.
Hope you got an idea

I would keep in your root component what the user have already typed, and the last suggestion data shown. I would also pass these state members to the children.
I would go with something like this:
this.state = {
text: "",
}
...
<InputSearch value={this.state.text} />
// 1st case:
<SearchHints query={this.state.text} />
// 2nd case:
<SearchHints hints={arrayOfSuggestions} />
// 3rd case:
<SearchHints>
<Hint someProps />
<Hint someProps />
<Hint someProps />
</SearchHints>
In the first case, your element SearchHints looks for the suggestions.
Otherwise, you have to give it either an array of props or an array of children with the suggestions.

Related

Best way to get values from multiple complex child components?

I have a parent component that has base data called script, which has multiple sequences and each sequence is composed of multiple items (inputs, dropdown, ... ).
Now I need the updated data in parent since I want to put a save button that is going to save all forms with one click.
It looks something like this:
I tried two ways of handling this:
That each child had an onChange property
in which parent sets the state with the new data. But the problem
here is, that since this is quite a complex form, it re-renders
everything each time, so there was a noticeable delay when typing in
inputs.
The "bad" of just changing the props object in a child,
which is fast, but I know it is a bad practice.
What is the best way of handling forms on a scale like this? Should it be set up differently?
This is a question I've spent some time struggling with myself. There are multiple ways to maintain child state at a higher level; however, I've found that in your particular situation it is often best to use Redux.
To be clear, I generally avoid Redux at all costs (in favor of React's context), but Redux gives you the ability to subscribe to a particular piece of state in your child components. Listening to one piece of state in a child component will prevent your parent and sibling components from updating when you only need a single child to update. This ends up being far more efficient when handling multiple forms at one time.
For example, the following component will only listen to state updates that affect its own state. These updates will bypass the forms parent and sibling components:
import React from 'react';
import { connect } from 'react-redux';
import * as actions from 'redux/actions';
// Custom component
import { InputField } from 'shared';
const FormOne = ({ me, actions }) => (
<form>
<InputField
inputId="f1f1"
label="field one"
value={me.fieldOne}
onChange={(e) => actions.setFormOneFieldOne(e.target.value)}
/>
<InputField
inputId="f1f2"
label="field two"
value={me.fieldTwo}
onChange={(e) => actions.setFormOneFieldTwo(e.target.value)}
/>
<InputField
inputId="f1f3"
label="field three"
value={me.fieldThree}
onChange={(e) => actions.setFormOneFieldThree(e.target.value)}
/>
</form>
);
export default connect(state => ({ me: state.formOne }), actions)(FormOne);
In the above example FormOne is only listening for its own state updates; whereas, similar logic utilizing context instead of Redux will cause the entire component tree that the context provider is wrapping to update (including parent and sibling components):
import React, { useContext } from 'react';
// Custom component
import { InputField } from 'shared';
// Custom context - below component must be wrapped with the provider
import { FormContext } from 'context';
const FormTwo = () => {
const context = useContext(FormContext);
return(
<form>
<InputField
inputId="f2f1"
label="field one"
value={context.state.formTwo.fieldOne}
onChange={(e) => context.setFormTwoFieldOne(e.target.value)}
/>
<InputField
inputId="f2f2"
label="field two"
value={context.state.formTwo.fieldTwo}
onChange={(e) => context.setFormTwoFieldTwo(e.target.value)}
/>
<InputField
inputId="f2f3"
label="field three"
value={context.state.formTwo.fieldThree}
onChange={(e) => context.setFormTwoFieldThree(e.target.value)}
/>
</form>
);
};
export default FormTwo;
There are some improvements that can be made to both of the above components, but they are meant to serve as an example for how to connect child components to an elevated state. It is also possible to connect to a single parent component using props, but that is the least efficient option possible, and will clutter up your architecture.
Key takeaway: Use Redux for your use case. It's the most efficient option if it is implemented correctly.
Good luck!
Wrap all the forms in a component that will only deal with saving all the forms data and running the "save all" function:
the wrapper component should have a state the includes all the forms data, it should probably look something like this:
class Wrapper Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formsData: {},
};
}
}
formsData should probably be structured pretty much like that:
{ 0: { title:"text", type:"video", etc:"etc" },
1: { title:"text", type:"video", etc:"etc" }}
the keys (0,1, etc..) represents the form id, and can be set to any unique modifier each for has.
then make the wrapper component handle the onChange for every individual form -> every change on each individual form should uplift the new state (new updated data) and update the formsData state obj accordingly:
const onChange(formData) {
const formattedData = {[formData.id]: {...formData}}
this.setState({formsData: {...formsData, ...formattedData}})
}
* This is just an example of a case where in each change in each form you uplift the entire data object, you can do it in many ways
Than, the save all button should also be handled in the wrapper component, and uplift all the data you stored with it to the relevant function in a parent component / handle it itself.
Good luck!
Lifting state up is indeed the correct way of doing this. To optimize child sections you can use
PureComponent ==> https://reactjs.org/docs/react-api.html#reactpurecomponent
AKA Memoized Component ==> https://reactjs.org/docs/react-api.html#reactmemo
React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of classes.
Also if you are within the hooks universe checkout
useCallback : https://reactjs.org/docs/hooks-reference.html#usecallback
useMemo : https://reactjs.org/docs/hooks-reference.html#usememo
If you are using Redux by any chance remember to look at
reselect : https://github.com/reduxjs/reselect

What is meant by parent component and child component in the sense of react and react native?

I am new to React & React Native, and doing my best to learn it well. During the learning i came to the lesson props and state but here one thing makes me confused and that is parent component and child component.
When we create a component in the React or React Native it is created like that:
export default class myApp extends React.Component{
render(){
return(
// Do something ...
);
}
}
And that's it. So, why people say parent component and child component and so on.
Is the React.Component is the parent component or is the myApp is child component. How parent and child components communicate via the props and state. Can please someone explain in easy words along with few examples, i will be glad.
Thanks !!!
In React.js and React Native, you render UI with components. So let say you want to build a House component. But first, you build a set of different components that you are going to use as building blocks such as a Door, Wall and Window components. Then you are going to use these components in your House's render function to render it. These building blocks components in this example are child components and the House component is their parent component.
On a side note, this concept originally comes from the DOM although there you talk about nodes (parent node, etc) rather than components.
React.Component is a parent for myApp component class.
While 'parent' and 'child' alone refer to React component hierarchy. myApp component is a parent for Foo component, and Foo component is a child of myApp component:
export default class myApp extends React.Component{
state = { foo: true };
render(){
return(
<Foo foo={this.state.foo} />
);
}
}
Parent and child component can communicate through props in one direction. A parent can pass something (e.g. its own state) to a child through props.
As commented,
In a component based architecture, you will have a HOC which will call your custom component and that will internally call some generic component. So with respect to your custom component, HOC is a parent component which will supply props. Your component will maintain its state, and based on provided props and computed state, you will pass props to this generic component, which is a child component.
TL;DR
Example:
Requirement:
You are trying to create a form that will accept 2 numbers and display their total.
What you need:
A form component that will create 2 input fields.
A input component that will accept value and return it to the caller.
A validator that will check if the value entered is a number or not.
A label to display total.
An event to process inputs.
Implementation:
You start in a ground-up fashion with input components. You cannot use <input type='text' as it will not have your custom validator. You cannot use <input type='number' as it adds spinner. So you create a custom component which uses type="text" and write your own validator
Now for this component, its value cannot be the value entered by user as it can be NaN. So you need a variable to store the processed value. You also need this value to be created once and not every time to persist its value. This place is called state.
Now that you have an input component, you need to stitch it together. So you create a form with your custom components and uses handlers/functions for communication. These functions passed to components are called as props.
So, to summarize, state is something you as a component will hold and prop is what you get from external environment (say some component).
Now, in this component tree, who do you call parent/child component? It is always referred based on a context. So in above example, w.r.t CustomInput component, since FormComponent is calling it, that is its parent. Similarly, any component it is calling will be its child component.
The parent/child component is an intuition not only the react/react native but to all mark up in general.
I assume you are conversant with html tag.
<div class='parent'>
<div class='child'></div
</div>
From the script above div.parent is a parent tag to div.child and vice versa.
Similarly in react
export default class myApp extends React.Component{
state = { foo: true };
render(){
return(
<Foo foo={this.state.foo} />
);
}
}
Foo is a child to myApp and myApp is parent to Foo.
This intuition is same in any mark up language

Passing props to a component through state

Prefix:
I am working with react-native, and am wondering the best practice for passing props down from a parent to a child component. I have tested this on my android device only.
Question:
From my understanding it is possible to pass values to a component through the use of props, ie:
<myComponent myProp="some data" />
and it can be referenced in my myComponent using this.props.myProp. Would it be bad practice (or will it even work) to create my state object in the constructor like so:
constructor(props){
super(props);
this.state = {
myStateProp: this.props.myProp
};
}
which could then be called in that component as this.state.myStateProp. I am relatively new to react-native and am trying to learn as much as I can. I have tried it in several use cases with varying results, and am uncertain as to the behavior. Thank you for your input!
There are few good reasons to do this. It's generally considered an anti-pattern because components should be stateless wherever possible.
If what you're trying to do is control the component by passing in props and using as state, I would suggest holding the state in the parent component and then passing any changes back up the chain via props, using a callback.
For example
ComponentOne {
this.state = { colour:red }
handleColourChange(val){
this.setState({ colour: val })
}
return <ComponentTwo changeColour={this.handleColourChange} colour={this.state.colour} />
}
Then imagine in ComponentTwo we have a button and you want to change colour:
<button onClick={this.changeColour(blue)}>Change to blue</button>
This way your child component remains stateless, and is controlled by its parent. this.props.colour will change in the child automatically.

ReactJS - Lifting state up vs keeping a local state

At my company we're migrating the front-end of a web application to ReactJS.
We are working with create-react-app (updated to v16), without Redux.
Now I'm stuck on a page which structure can be simplified by the following image:
The data displayed by the three components (SearchableList, SelectableList and Map) is retrieved with the same backend request in the componentDidMount() method of MainContainer. The result of this request is then stored in the state of MainContainer and has a structure more or less like this:
state.allData = {
left: {
data: [ ... ]
},
right: {
data: [ ... ],
pins: [ ... ]
}
}
LeftContainer receives as prop state.allData.left from MainContainer and passes props.left.data to SearchableList, once again as prop.
RightContainer receives as prop state.allData.right from MainContainer and passes props.right.data to SelectableList and props.right.pins to Map.
SelectableList displays a checkbox to allow actions on its items. Whenever an action occur on an item of SelectableList component it may have side effects on Map pins.
I've decided to store in the state of RightContainer a list that keeps all the ids of items displayed by SelectableList; this list is passed as props to both SelectableList and Map. Then I pass to SelectableList a callback, that whenever a selection is made updates the list of ids inside RightContainer; new props arrive in both SelectableList and Map, and so render() is called in both components.
It works fine and helps to keep everything that may happen to SelectableList and Map inside RightContainer, but I'm asking if this is correct for the lifting-state-up and single-source-of-truth concepts.
As feasible alternative I thought of adding a _selected property to each item in state.right.data in MainContainer and pass the select callback three levels down to SelectableList, handling all the possible actions in MainContainer. But as soon as a selection event occurs this will eventually force the loading of LeftContainer and RightContainer, introducing the need of implementing logics like shouldComponentUpdate() to avoid useless render() especially in LeftContainer.
Which is / could be the best solution to optimise this page from an architectural and performance point of view?
Below you have an extract of my components to help you understand the situation.
MainContainer.js
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
allData: {}
};
}
componentDidMount() {
fetch( ... )
.then((res) => {
this.setState({
allData: res
});
});
}
render() {
return (
<div className="main-container">
<LeftContainer left={state.allData.left} />
<RightContainer right={state.allData.right} />
</div>
);
}
}
export default MainContainer;
RightContainer.js
class RightContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedItems: [ ... ]
};
}
onDataSelection(e) {
const itemId = e.target.id;
// ... handle itemId and selectedItems ...
}
render() {
return (
<div className="main-container">
<SelectableList
data={props.right.data}
onDataSelection={e => this.onDataSelection(e)}
selectedItems={this.state.selectedItems}
/>
<Map
pins={props.right.pins}
selectedItems={this.state.selectedItems}
/>
</div>
);
}
}
export default RightContainer;
Thanks in advance!
As React docs state
Often, several components need to reflect the same changing data. We
recommend lifting the shared state up to their closest common
ancestor.
There should be a single “source of truth” for any data that changes
in a React application. Usually, the state is first added to the
component that needs it for rendering. Then, if other components also
need it, you can lift it up to their closest common ancestor. Instead
of trying to sync the state between different components, you should
rely on the top-down data flow.
Lifting state involves writing more “boilerplate” code than two-way
binding approaches, but as a benefit, it takes less work to find and
isolate bugs. Since any state “lives” in some component and that
component alone can change it, the surface area for bugs is greatly
reduced. Additionally, you can implement any custom logic to reject or
transform user input.
So essentially you need to lift those state up the tree that are being used up the Siblings component as well. So you first implementation where you store the selectedItems as a state in the RightContainer is completely justified and a good approach, since the parent doesn't need to know about and this data is being shared by the two child components of RightContainer and those two now have a single source of truth.
As per your question:
As feasible alternative I thought of adding a _selected property to
each item in state.right.data in MainContainer and pass the select
callback three levels down to SelectableList, handling all the
possible actions in MainContainer
I wouldn't agree that this is a better approach than the first one, since you MainContainer doesn't need to know the selectedItems or handler any of the updates. MainContainer isn't doing anything about those states and is just passing it down.
Consider to optimise on performance, you yourself talk about implementing a shouldComponentUpdate, but you can avoid that by creating your components by extending React.PureComponent which essentially implements the shouldComponentUpdate with a shallow comparison of state and props.
According to the docs:
If your React component’s render() function renders the same result
given the same props and state, you can use React.PureComponent for a
performance boost in some cases.
However if multiple deeply nested components are making use of the same data, it makes sense to make use of redux and store that data in the redux-state. In this way it is globally accessible to the entire App and can be shared between components that are not directly related.
For example consider the following case
const App = () => {
<Router>
<Route path="/" component={Home}/>
<Route path="/mypage" component={MyComp}/>
</Router>
}
Now here if both Home and MyComp want to access the same data. You could pass the data as props from App by calling them through render prop. However it would easily be done by connecting both of these components to Redux state using a connect function like
const mapStateToProps = (state) => {
return {
data: state.data
}
}
export connect(mapStateToProps)(Home);
and similarly for MyComp. Also its easy to configure actions for updating relevant informations
Also its particularly easy to configure Redux for your application and you would be able to store data related to the same things in the individual reducers. In this way you would be able to modularise your application data as well
My honest advice on this. From experience is:
Redux is simple. It's easy to understand and scale BUT you should use Redux for some specific use cases.
Since Redux encapsulates your App you can think of storing stuff like:
current app locale
current authenticated user
current token from somewhere
Stuff that you would need on a global scale. react-redux even allows for a #connect decorator on components. So like:
#connect(state => ({
locale: state.locale,
currentUser: state.currentUser
}))
class App extends React.Component
Those are all passed down as props and connect can be used anywhere on the App. Although I recommend just passing down the global props with the spread operator
<Navbar {...this.props} />
All other components (or "pages") inside your app can do their own encapsulated state. For example the Users page can do it's own thing.
class Users extends React.Component {
constructor(props) {
super(props);
this.state = {
loadingUsers: false,
users: [],
};
}
......
You would access locale and currentUser through props because they were passed down from the Container components.
This approach I've done it multiple times and it works.
But, since you wanted to really consolidate the knowledge of React first, before doing Redux you can just store your state on the top-level component and pass it down to the children.
Downsides:
You're gonna have to keep passing them down into inner level components
To update state from the inner level components you're gonna have to pass the function that updates the state.
These downsides are a little boring and cumbersome to manage. That's why Redux was built.
Hope I helped. good luck
By using Redux you can avoid such callbacks and maintain the whole state in one single store - so make your parent component connected component - and make left and right components dumb ones - and just pass in the props you get from parent to child - and you don't have to worry about callbacks in this case.

What is the difference between state and props in React?

I was watching a Pluralsight course on React and the instructor stated that props should not be changed. I'm now reading an article (uberVU/react-guide) on props vs. state and it says
Both props and state changes trigger a render update.
Later in the article it says:
Props (short for properties) are a Component's configuration, its options if you may. They are received from above and immutable.
So props can change but they should be immutable?
When should you use props and when should you use state?
If you have data that a React component needs, should it be passed through props or setup in the React component via getInitialState?
Props and state are related. The state of one component will often become the props of a child component. Props are passed to the child within the render method of the parent as the second argument to React.createElement() or, if you're using JSX, the more familiar tag attributes.
<MyChild name={this.state.childsName} />
The parent's state value of childsName becomes the child's this.props.name. From the child's perspective, the name prop is immutable. If it needs to be changed, the parent should just change its internal state:
this.setState({ childsName: 'New name' });
and React will propagate it to the child for you. A natural follow-on question is: what if the child needs to change its name prop? This is usually done through child events and parent callbacks. The child might expose an event called, for example, onNameChanged. The parent would then subscribe to the event by passing a callback handler.
<MyChild name={this.state.childsName} onNameChanged={this.handleName} />
The child would pass its requested new name as an argument to the event callback by calling, e.g., this.props.onNameChanged('New name'), and the parent would use the name in the event handler to update its state.
handleName: function(newName) {
this.setState({ childsName: newName });
}
For parent-child communication, simply pass props.
Use state to store the data your current page needs in your controller-view.
Use props to pass data & event handlers down to your child components.
These lists should help guide you when working with data in your components.
Props
are immutable
which lets React do fast reference checks
are used to pass data down from your view-controller
your top level component
have better performance
use this to pass data to child components
State
should be managed in your view-controller
your top level component
is mutable
has worse performance
should not be accessed from child components
pass it down with props instead
For communication between two components that don't have a
parent-child relationship, you can set up your own global event
system. Subscribe to events in componentDidMount(), unsubscribe in
componentWillUnmount(), and call setState() when you receive an event.
Flux pattern is one of the possible ways to arrange this.
- https://facebook.github.io/react/tips/communicate-between-components.html
What Components Should Have State?
Most of your components should simply take some data from props and
render it. However, sometimes you need to respond to user input, a
server request or the passage of time. For this you use state.
Try to keep as many of your components as possible stateless. By doing
this you'll isolate the state to its most logical place and minimize
redundancy, making it easier to reason about your application.
A common pattern is to create several stateless components that just
render data, and have a stateful component above them in the hierarchy
that passes its state to its children via props. The stateful
component encapsulates all of the interaction logic, while the
stateless components take care of rendering data in a declarative way.
- https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-components-should-have-state
What Should Go in State?
State should contain data that a component's event handlers may change
to trigger a UI update. In real apps this data tends to be very small
and JSON-serializable. When building a stateful component, think about
the minimal possible representation of its state, and only store those
properties in this.state. Inside of render() simply compute any other
information you need based on this state. You'll find that thinking
about and writing applications in this way tends to lead to the most
correct application, since adding redundant or computed values to
state means that you need to explicitly keep them in sync rather than
rely on React computing them for you.
- https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-should-go-in-state
You can understand it best by relating it to Plain
JS functions.
Simply put,
State is the local state of the component which cannot be accessed and modified outside of the component. It's equivalent to local variables in a function.
Plain JS Function
const DummyFunction = () => {
let name = 'Manoj';
console.log(`Hey ${name}`)
}
React Component
class DummyComponent extends React.Component {
state = {
name: 'Manoj'
}
render() {
return <div>Hello {this.state.name}</div>;
}
Props, on the other hand, make components reusable by giving components the ability to receive data from their parent component in the form of props. They are equivalent to function parameters.
Plain JS Function
const DummyFunction = (name) => {
console.log(`Hey ${name}`)
}
// when using the function
DummyFunction('Manoj');
DummyFunction('Ajay');
React Component
class DummyComponent extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
// when using the component
<DummyComponent name="Manoj" />
<DummyComponent name="Ajay" />
Credits: Manoj Singh Negi
Article Link: React State vs Props explained
The props vs state summary I like best is here: react-guide Big hat tip to those guys. Below is an edited version of that page:
props vs state
tl;dr If a Component needs to alter one of its attributes at some point in time, that attribute should be part of its state, otherwise it should just be a prop for that Component.
props
Props (short for properties) are a Component's configuration. They are received from above and immutable as far as the Component receiving them is concerned. A Component cannot change its props, but it is responsible for putting together the props of its child Components. Props do not have to just be data -- callback functions may be passed in as props.
state
The state is a data structure that starts with a default value when a Component mounts. It may be mutated across time, mostly as a result of user events.
A Component manages its own state internally. Besides setting an initial state, it has no business fiddling with the state of its children. You might conceptualize state as private to that component.
Changing props and state
props state
Can get initial value from parent Component? Yes Yes
Can be changed by parent Component? Yes No
Can set default values inside Component?* Yes Yes
Can change inside Component? No Yes
Can set initial value for child Components? Yes Yes
Can change in child Components? Yes No
Note that both props and state initial values received from parents override default values defined inside a Component.
Should this Component have state?
State is optional. Since state increases complexity and reduces predictability, a Component without state is preferable. Even though you clearly can't do without state in an interactive app, you should avoid having too many Stateful Components.
Component types
Stateless Component Only props, no state. There's not much going on besides the render() function. Their logic revolves around the props they receive. This makes them very easy to follow, and to test.
Stateful Component Both props and state. These are used when your component must retain some state. This is a good place for client-server communication (XHR, web sockets, etc.), processing data and responding to user events. These sort of logistics should be encapsulated in a moderate number of Stateful Components, while all visualization and formatting logic should move downstream into many Stateless Components.
sources
Question about 'props' and 'state' - Google Groups
Thinking in React: Identify where your state should live
The key difference between props and state is that state is internal and controlled by the component itself while props are external and controlled by whatever renders the component.
function A(props) {
return <h1>{props.message}</h1>
}
render(<A message=”hello” />,document.getElementById(“root”));
class A extends React.Component{
constructor(props) {
super(props)
this.state={data:"Sample Data"}
}
render() {
return(<h2>Class State data: {this.state.data}</h2>)
}
}
render(<A />, document.getElementById("root"));
State can be changed (Mutable)
Whereas Props can't (Immutable)
props (short for “properties”) and state are both plain JavaScript
objects. While both hold information that influences the output of
render, they are different in one important way: props get passed to
the component (similar to function parameters) whereas state is
managed within the component (similar to variables declared within a
function).
So simply state is limited to your current component but props can be pass to any component you wish... You can pass the state of the current component as prop to other components...
Also in React, we have stateless components which only have props and not internal state...
The example below showing how they work in your app:
Parent (state-full component):
class SuperClock extends React.Component {
constructor(props) {
super(props);
this.state = {name: "Alireza", date: new Date().toLocaleTimeString()};
}
render() {
return (
<div>
<Clock name={this.state.name} date={this.state.date} />
</div>
);
}
}
Child (state-less component):
const Clock = ({name}, {date}) => (
<div>
<h1>{`Hi ${name}`}.</h1>
<h2>{`It is ${date}`}.</h2>
</div>
);
Basically, the difference is that state is something like attributes in OOP : it's something local to a class (component), used to better describe it. Props are like parameters - they are passed to a component from the caller of a component (the parent) : as if you called a function with certain parameters.
Both state and props in react are used to control data into a component, generally props are set by parent and passed to child components and they are fixed throughout the component. For data that is going to change, we have to use state. And props are immutable while states are mutable, if you want to change props you can do from parent component and then pass it to child components.
as I learned while working with react.
props are used by a component to get data from external environment i.e another component ( pure, functional or class) or a general class or javascript/typescript code
states are used to manage the internal environment of a component means the data changes inside the component
Props : Props is nothing but property of component and react component is nothing but a javascript function.
class Welcome extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
const element = ;
here <Welcome name="Sara" /> passing a object {name : 'Sara'} as props of Welcome component. To pass data from one parent component to child component we use props.
Props is immutable. During a component’s life cycle props should not change (consider them immutable).
State: state is accessible only within Component. To keep track of data within component we use state. we can change state by setState. If we need to pass state to child we have to pass it as props.
class Button extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}
State:
states are mutable.
states are associated with the individual components can't be used by other components.
states are initialize on component mount.
states are used for rendering dynamic changes within component.
props:
props are immutable.
you can pass props between components.
props are mostly used to communicate between components.You can pass from parent to child directly. For passing from child to parent
you need use concept of lifting up states.
class Parent extends React.Component{
render()
{
return(
<div>
<Child name = {"ron"}/>
</div>
);
}
}
class Child extends React.Component{
{
render(){
return(
<div>
{this.props.name}
</div>
);
}
}
state - It is a special mutable property that hold a Component data. it has default value when Componet mounts.
props - It is a special property which is immutable by nature and used in case of pass by value from parent to child. props are just a communation channel between Components, always moving from top (parent) to buttom(child).
below are complete example of combinding the state & props :-
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>state&props example</title>
<script src="https://unpkg.com/react#0.14.8/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom#0.14.8/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
var TodoList = React.createClass({
render(){
return <div className='tacos-list'>
{
this.props.list.map( ( todo, index ) => {
return <p key={ `taco-${ index }` }>{ todo }</p>;
})}
</div>;
}
});
var Todo = React.createClass({
getInitialState(){
return {
list : [ 'Banana', 'Apple', 'Beans' ]
}
},
handleReverse(){
this.setState({list : this.state.list.reverse()});
},
render(){
return <div className='parent-component'>
<h3 onClick={this.handleReverse}>List of todo:</h3>
<TodoList list={ this.state.list } />
</div>;
}
});
ReactDOM.render(
<Todo/>,
document.getElementById('root')
);
</script>
</body>
</html>
Props: represents "read-only" data, that are immutable and refer to attributes from parents component.
State: represents mutable data, that ultimately affects what is rendered on the page and managed by internally by the component itself and change overtime commonly due to User input.
Props
props use to pass data in the child component
props change a value outside a component(child component)
State
state use inside a class component
state change a value inside a component
If you render the page, you call setState to update DOM(update page
value)
State has an important role in react
Basically, props and state are two ways the component can know what and how to render. Which part of the application state belongs to state and which to some top-level store, is more related to your app design, than to how React works. The simplest way to decide, IMO, is to think, whether this particular piece of data is useful for application as a whole, or it's some local information. Also, it's important to not duplicate state, so if some piece of data can be calculated from props - it should calculated from props.
For example, let's say you have some dropdown control (which wraps standart HTML select for custom styling), which can a) select some value from list, and b) be opened or closed (i.e., the options list displayed or hidden).
Now, let's say your app displays a list of items of some sort and your dropdown controls filter for list entries. Then, it would be best to pass active filter value as a prop, and keep opened/closed state local. Also, to make it functional, you would pass an onChange handler from parent component, which would be called inside dropdown element and send updated information (new selected filter) to the store immediately. On the other hand, opened/closed state can be kept inside dropdown component, because the rest of the application doesn't really care if the control is opened, until user actually changes it value.
The following code is not completely working, it needs css and handling dropdown click/blur/change events, but I wanted to keep example minimal. Hope it helps to understand the difference.
const _store = {
items: [
{ id: 1, label: 'One' },
{ id: 2, label: 'Two' },
{ id: 3, label: 'Three', new: true },
{ id: 4, label: 'Four', new: true },
{ id: 5, label: 'Five', important: true },
{ id: 6, label: 'Six' },
{ id: 7, label: 'Seven', important: true },
],
activeFilter: 'important',
possibleFilters: [
{ key: 'all', label: 'All' },
{ key: 'new', label: 'New' },
{ key: 'important', label: 'Important' }
]
}
function getFilteredItems(items, filter) {
switch (filter) {
case 'all':
return items;
case 'new':
return items.filter(function(item) { return Boolean(item.new); });
case 'important':
return items.filter(function(item) { return Boolean(item.important); });
default:
return items;
}
}
const App = React.createClass({
render: function() {
return (
<div>
My list:
<ItemList items={this.props.listItems} />
<div>
<Dropdown
onFilterChange={function(e) {
_store.activeFilter = e.currentTarget.value;
console.log(_store); // in real life, some action would be dispatched here
}}
filterOptions={this.props.filterOptions}
value={this.props.activeFilter}
/>
</div>
</div>
);
}
});
const ItemList = React.createClass({
render: function() {
return (
<div>
{this.props.items.map(function(item) {
return <div key={item.id}>{item.id}: {item.label}</div>;
})}
</div>
);
}
});
const Dropdown = React.createClass({
getInitialState: function() {
return {
isOpen: false
};
},
render: function() {
return (
<div>
<select
className="hidden-select"
onChange={this.props.onFilterChange}
value={this.props.value}>
{this.props.filterOptions.map(function(option) {
return <option value={option.key} key={option.key}>{option.label}</option>
})}
</select>
<div className={'custom-select' + (this.state.isOpen ? ' open' : '')} onClick={this.onClick}>
<div className="selected-value">{this.props.activeFilter}</div>
{this.props.filterOptions.map(function(option) {
return <div data-value={option.key} key={option.key}>{option.label}</div>
})}
</div>
</div>
);
},
onClick: function(e) {
this.setState({
isOpen: !this.state.isOpen
});
}
});
ReactDOM.render(
<App
listItems={getFilteredItems(_store.items, _store.activeFilter)}
filterOptions={_store.possibleFilters}
activeFilter={_store.activeFilter}
/>,
document.getElementById('root')
);
State is the way react deals with the information held by your component.
Let's suppose you have a component which need to fetch some data from the server. You usually would want to inform the user if the request is processing, if it has failed, etc. This is a piece of information which is just relevant for that specific component. This is where state enters the game.
Usually the best way to define state is as follows:
class MyComponent extends React.Component {
constructor() {
super();
this.state = { key1: value1, key2: value2 }
}
}
but in the latests implementations of react native you can just do:
class MyComponent extends React.Component {
state = { key1: value1, key2: value2 }
}
These two examples execute in the exact same way, it's just a syntax improvement.
So, what is different from just using object attributes as we always have in OO programming? Usually, the information held in your state is not meant to be static, it will change over time and your View will need to update in order to reflect this changes. State offers this functionality in a simple way.
State IS MEANT TO BE INMUTABLE! and I cannot make enough stress on this. What does this means? It means that you should NEVER do something like this.
state.key2 = newValue;
The proper way of doing it is:
this.setState({ key2: newValue });
Using this.setState your component runs through the update cycle and if any part of the state changes, your Component render method will be called again to reflect this changes.
Check the react docs for an even more expanded explanation:
https://facebook.github.io/react/docs/state-and-lifecycle.html
Props simply are shorthand for properties. Props are how components talk to each other. If you’re at all familiar with React then you should know that props flow downwards from the parent component.
There is also the case that you can have default props so that props are set even if a parent component doesn’t pass props down.
This is why people refer to React as having uni-directional data flow. This takes a bit of getting your head around and I’ll probably blog on this later, but for now just remember: data flows from parent to child. Props are immutable (fancy word for it not changing)
So we’re happy. Components receive data from the parent. All sorted, right?
Well, not quite. What happens when a component receives data from someone other than the parent? What if the user inputs data directly to the component?
Well, this is why we have state.
STATE
Props shouldn’t change, so state steps up. Normally components don’t have state and so are referred to as stateless. A component using state is known as stateful. Feel free to drop that little tidbit at parties and watch people edge away from you.
So state is used so that a component can keep track of information in between any renders that it does. When you setState it updates the state object and then re-renders the component. This is super cool because that means React takes care of the hard work and is blazingly fast.
As a little example of state, here is a snippet from a search bar (worth checking out this course if you want to learn more about React)
Class SearchBar extends Component {
constructor(props) {
super(props);
this.state = { term: '' };
}
render() {
return (
<div className="search-bar">
<input
value={this.state.term}
onChange={event => this.onInputChange(event.target.value)} />
</div>
);
}
onInputChange(term) {
this.setState({term});
this.props.onSearchTermChange(term);
}
}
SUMMARY
Props and State do similar things but are used in different ways. The majority of your components will probably be stateless.
Props are used to pass data from parent to child or by the component itself. They are immutable and thus will not be changed.
State is used for mutable data, or data that will change. This is particularly useful for user input. Think search bars for example. The user will type in data and this will update what they see.
In short.
props values can't be changed [immutable]
state values can be changed, using setState method [mutable]
In general, state of one component(parent) is prop for the child component.
State resides within a component where as props are passed from parent to
child.
Props are generally immutable.
class Parent extends React.Component {
constructor() {
super();
this.state = {
name : "John",
}
}
render() {
return (
<Child name={this.state.name}>
)
}
}
class Child extends React.Component {
constructor() {
super();
}
render() {
return(
{this.props.name}
)
}
}
In the above code, we have a parent class(Parent) which has name as its state which is passed to the child component(Child class) as a prop and the child component renders it using {this.props.name}
In React the states store the data as well as the props. Its difference with the latter is that the stored data can be modified by different changes. These are nothing more than objects written in flat JavaScript, so they can contain data or codes, represent the information you want to model. If you need more details it is recommended that you see these publications
Use of the State in React and
Use of Props in React
The key difference between props and state is that state is internal and controlled by the component itself while props are external and controlled by whatever renders the component.
In answer to the initial question about props being immutable, they are said to be immutable as far as the child component is concerned but are of course changeable in the parent that is passing these props down.
A change in these in the parent will trigger a re-render of the child component with the updated props.
This is my current point of view regarding the explanation between state and props
State is like your local variable inside your component. You can manipulate
the value of state by using set state. You can then pass the value of state
to your child component for example.
Props is the value that exactly located inside your redux store, this actually
comes from state that's originated from reducer. Your component
should be connected to redux to get the value from props. You can also pass
your props value to your child component
You have some data that is being entered by users somewhere in the application.
the component in which the data is being entered should have this data in its state because it needs to manipulate and change it during data entry
anywhere else in the application the data should be passed down as props to all the other components
So yes the props are changing but they are changed at the 'source' and will then simply flow down from there. So props are immutable in the context of the component receiving them.
E.g. a reference data screen where users edit a list of suppliers would manage this in state, which would then have an action cause the updated data to be saved in ReferenceDataState which could be one level below AppState and then this supplier list would be passed as props to all the components that needed to use it.
Some differences between “state” and “props” in react.
React controls and renders DOM based on state. There are two types of component states: props is the state that transfers between components, and state is internal state of components. Props is used for data transfer from the parent component to the child component. The components also have their own state inside: state which can only be modified inside the component.
Generally the state of certain component could be the props of the child component ,props will be passed to children which is stated inside the rendering method of the parent component
From: Andrea Chiarelli book “Beginning React: Simplify your frontend development workflow and enhance the user experience of your applications with React” :
Every React component has a props property. The purpose of this property is to collect data input passed to the component itself. JSX attribute is attached to a React element, a property with the same name is attached to the props object. So, we can access the passed data by using the attached property. In addition, the immutability of props allows us to think of components as pure functions, which are functions that have no side effects (since they don't change their input data). We can think of data passing from one component to another as a unidirectional data flow, from the parent component toward the child components. This gives us a more controllable system.
React provides a mechanism to support the automatic rendering of a component when data changes. Such a mechanism is based on the concept of state. React state is a property that represents data that changes over time. Every component supports the state property, but it should be used carefully. Components that store data that can change over time are said to be stateful components. A stateful component stores the state in the this.state property. To inform a component that the state has changed, you must use the setState() method. State initialization is the only case where you can assign a value to the this.state property without using setState().
setState() merges new data with old data already contained in the state, and overwrites the previous state
setState() triggers the execution of the render() method, so you should never call render() explicitly
State is a special variable in react and is used to re-render component whenever it updates
State is private to the component itself. I.e, it cannot be accessed or modified outside of component. setState/hook used to update state. Whenever state update, component re renders
State is mutable
Props are inputs to component and render content using props data
Props are immutable(Object.Frozen= true)
we can change states value but we can not change props value , or we can say props is immutable and states is mutable
I want to explain state and props in a simple way to you:
state
we use states to store some data. it's also like a variable that when you change it, your component will render again.
to use states you need to import useState hook:
import { useState } from 'react';
const [state_name,function_name] = useState(initial_value);
you can access your state by state_name and you can change it and set a new value to it by function_name.
more info: https://reactjs.org/docs/state-and-lifecycle.html
props
It is a mechanism to send data from one component to other. it also looks like properties in CSS. for example:
<Component props_value={custom_function} />
you can send a custom function to Component and receive it to be manipulate.
more info: https://reactjs.org/docs/components-and-props.html
React Components use state to READ/WRITE the internal variables that can be changed/mutated by for example:
this.setState({name: 'Lila'})
React props is special object that allow programmer to get variables and methods from Parent Component into Child Component.
It's something like a Windows and doors of the house. Props are also immutable Child Component can not change/update them.
There are couple of the methods that help to listen when props are changed by Parent Component.

Categories

Resources