Data storing of React Components - javascript

I am thinking of creating a list components which receive list of items and then return a list of <li></li>. Moreover, the list can be appended dynamically via ajax call.
I would like to ask in this situation, where should I store the data, props or state?

In most cases: use state for data that changes over time.
A common way of doing this is to have two components, List and ListItem. The List component should handle the state, ajax calls and the transfer of list content as props to the child component ListItem.
<List>
<ListItem>
<ListItem>
<ListItem>
...
</List>
So List stores the data as state. And ListItem is stateless and just receive its data from List.
React docs: 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.
Maybe this helps to understand the structure of building react apps: Tutorial: Thinking in React

Related

Where should my `fetch` request be placed in my React app without having to pass data between the child and parent component?

I'm working on a project right now, where I have App.jsx, and my other components inputComponent and articleComponent. App.jsx contains both my inputComponent and my articleComponent. However, I've written the fetch request to be within inputComponent.
In this case, my articleComponent relies heavily on the data retrieved from the fetch request, and so I'm thinking, a possible solution would be to move the fetch from inputComponent to articleComponent. Another one was to use callbacks to pass data from the child component to the parent component. However, based on some answers I've read here and online, it seems that this method of passing data from the child component to the parent is a React anti-pattern as well.
I also think that the fetch call ideally shouldn't be on App.jsx, but feel free to correct me if I'm wrong.
Ideally, what I need is for the data retrieved from the fetch call (which comes from user input submission in inputComponent) to be able to be passed in as props to the ArticleComponent so that I can render the articles with the proper data after fetching it from my server. What would be the "React" way of doing it, and also the best way in general?
As #misternobody said, the 'normal' way is to pass data down to children as props and yes, if a parent's state change - it re-renders all of its children (that's the idea behind React).
So you would pass your input from inputComponent up to App (with the use of a callback passed as a prop), fetch inside your App, then pass the response down to ArticleComponent
If for some reason you want to dodge the rendering of App component in this process, you'd have to use ie. Redux and NOT connect App to the store. Then, if you'd properly map store's state and diapatch to props in your 'child' components, it should work as you intended without bothering App.
Normally the properties you want in all children sit in the parent class.
I would write the fetch right there, and pass it to the children as props.

React-Redux: Do I have to use connect() and map state/dispatch on all my components from a single component tree? Is there a way to do it only once?

So basically I have an app with a single component tree. App as a parent and then it goes down from there. Initially, all of the states are obviously centralized from the parent component App, as it is normally, and then the state is passed per component via props. We all know this is a hassle as the component tree gets bigger and bigger.
I'm studying React-Redux and just curious if I always have to use connect() and then each create a mapStateToProps and mapDispatchToProps for each and all my components including the subcomponents? Is there a one-off way to do this? Isn't it possible for my many components to just access the entire store without mapping each state/dispatch to props one-by-one, which I find repetitive and time-consuming?
I came from a Vue-Vuex background (although my Vuex experience is limited) and React-Redux is just a whole different ball wax, if not quite a lot more complicated IMO.
Per the Redux FAQ entry on "Should I connect all my components, or just one?":
Early Redux documentation advised that you should only have a few connected components near the top of your component tree. However, time and experience has shown that such a component architecture generally requires a few components to know too much about the data requirements of all their descendants, and forces them to pass down a confusing number of props.
Emphasizing “one container component at the top” in Redux examples was a mistake. Don't take this as a maxim. Try to keep your presentation components separate. Create container components by connecting them when it's convenient. Whenever you feel like you're duplicating code in parent components to provide data for same kinds of children, time to extract a container. Generally as soon as you feel a parent knows too much about “personal” data or actions of its children, time to extract a container.
In fact, benchmarks have shown that more connected components generally leads to better performance than fewer connected components.
In general, try to find a balance between understandable data flow and areas of responsibility with your components.
With Redux you don't have to connect all the components to its store. You only connect the components that really need it. For example, if a connected component has children then it might be simpler not to connect the childeren to Redux but rather let the connected parent drive the updates for its children. Grandkids can be coonected but not their immediate children and so forth. There can be many approaches and every component can still have its own private state in addition to Redux store.
Currently React.FunctionComponents are in fashion and you can use useReducer hook instead of connect though you will have less possibilities to fine-tune for performance with the hook.
Your state in redux store doesn't change, but in order to use it, you should use connect and connect to your store.
If you don't want to use connect,
you can simply pass your states to a child component by props like
<mycomponent data={this.state.data} />
And use your data in your child component
If these ways not satisfying you can read about the context system, but it's parent to the child again, but you can pass data from parent to grandchild without using child
You can read about it here
Hope this helps you.

Connecting child components to store vs connecting parent component to store and passing down props

After a lot of search and working with React and React Native. I still have a pretty vague opinion on which
is best to use and in what situations
Having the parent component be connected to the store and passing as props all data to children functional components. This what I initial though was the "React" way but pretty soon I saw that as the app grow the amount of logic handled by this parent component starting too be to big and messy.Also child components start to have children of its own and so on and so forth.
Having parent component (Screen for example) that is functional and each child that needs information from the store will be connected to it. This is much more "clean" solution but will create a lot of store connection "duplications" which are not necessary.
Using Redux store
My question in general which is more recommended pattern to use and in which use cases, also would be nice to know what is the price for having a lot of connected (containers) components
Not sure i can provide a right or wrong answer for this question as each has its pros and cons.
My rule of thumb is to connect deeply nested components only when their parents are "proxies of props". That is they accepts props only to pass them down to their children.
If i may quote (myself) from this answer:
Avoid connecting components when you can and pass down the props to
the children, the main reason for this is to prevent dependency on
redux. I prefer keep my components "dumb" as i can and let them
concern only on how things should look. I do have some components that
concern on how things should work and these components are mainly
dealing with logic and passing down data to the children, they are the
components i often connect.
When i notice that my app is scaling and some of my components are
acting as a proxy of props (i even got a word for that! "Propxy"),
that is they get props from their parent and pass them down without
using them, i usually inject a connected component in the middle of
the components tree so i can let the "propxy" components down the tree
flow be more lighten and slim
You should also note that one more pitfall with connected components is that each render will trigger the mapstateToProps method. if you got some heavy logic there you should memoize it, usually done with reselect
As for the benefit of connecting a component, well you probably realize that already. you get quick access to the Provider's state via react's context.
Edit
As a followup to your comment:
about the rendering - wont I have much more unnecessary rendering if Ill have a deep nested children (common in medium to large apps) that will be unnecessarily re rendered on each parent update
Well the connect HOC wrapper won't trigger a re-render if the previous object of mapStateToProps is the same as the current object returned. so no unnecessary re-renders to your connected component will take place.
You can read in more details on how it works and how the logic was evolved over time in this article
I use the first option.
The cons you wrote are correct, but i think its easier to debug and understand the data flow this way.
Don't connect a component to redux if the current component doesn't use this data from redux and only passes.
If the component uses data then connect to redux.
If the current component uses data from redux and the next component also uses it then you can pass and don't need to connect the next component to redux.
MAIN RULE:
if there is a gap in the data usage chain from parent to child then don't need to pass data from parent to child
connect(parent) (don't use props) => child (don't use) => child (don't use) => child (using) - better to connect last child. Isuue related to props dreeling

How does the root React component interact with the rest of the application?

So I have a working UI skeleton built using React. There's a root component that contains all of the state information, it has 2 child components: 1 that displays some of the state information (data), and 1 that contains buttons that can alter some of the state information via callbacks. If I initialize it with hard-coded dummy data it all works.
Then I have the actual meat of my application, which does not use React or Angular or Redux or anything of the sort, that I need to be able to alter the root component's state in some way (i.e. pass it the raw data to display).
Now, how do I actually couple the React UI with the separate business logic of my application? Or, how do I pass outside data into my root React component?
I'd really, really like to avoid adding more libraries.
One way to do it would be to have your outside code call
ReactDOM.render(
<Root propertyYouWantToUpdate={value} />,
documentGetElementById('your-root-element')
)
And inside your root component create a custom
componentWillReceiveProps(nextProps, nextState) {
// calculate new state based on nextProps and existing state...
this.setState(newCalculatedState)
}

How should child components in React communicate between each other in a clean and maintainable fashion?

I'm fairly new to React and I'm trying to understand a clean way for child components to communicate with each other.
In a simple component, I know that I can make use of props to pass data to child and callbacks for children to pass data back to parent component.
In a slightly more complex case, when I have multiple children components in a parent component, the communication between the children gets a little confusing. I'm not sure what I should do for children components of the same level to communicate with each other.
In my case, I decided that, maybe, I could use states. So I will have a state value in the parent component, and pass it on the children's props. Similarly, the callback handlers (called from the children component) in the parent component will help to set the states accordingly so that a state value gets passed on from one child to another through React's binding.
And a pseudo code could look something like:
//Inside Parent Component
constructor() {
//initialise state for the child components
this.setState({testList: []});
}
render() {
return (
<div>
<ChildA onSomething={this.onSomethingHandler} testList={this.state.testList} />
<ChildB onSomethingElse={this.onSomethingElseHandler} testList={this.state.testList} />
</div>
);
}
onSomethingHandler(evt):void {
if(blah.blah.blah) this.setState({testList: this.state.testList.splice().push(evt.value)};
}
onSomethingElseHandler(evt):void {
//Some other complex biz logic...
if(blah.blah.blah) this.setState({testList: this.state.testList.splice().push(somethingOtherStuffDueToLogic)};
}
//Inside ChildA Component
export IChildAProps {
onSomething: (evt)=>void
}
render() {
//Do some logic from the value in testList property
if(this.state.testList == blah blah)...
return (
<button onClick={this.props.onSomething({id:321, value:"wassup! I'm ChildA."})}>ChildA</button>
)
}
//Inside ChildB Component
export IChildBProps {
onSomethingElse: (evt)=>void
}
render() {
//Do some logic from the value in testList property
if(this.state.testList == blah blah)...
return (
<button onClick={this.props.onSomething({id:123, value:"yo! I'm ChildB."})}>ChildB</button>
)
}
At this point, I'm starting to wonder if the logic in that 2 handler methods, namely onSomethingHandler() and onSomethingElseHandler() in the Parent component, should actually be resided inside the child components themselves? I thought of this because those logic look like something the child component should be handling on their own to serve their purpose. The parent component shouldn't do it for them or it might just grow messy. But I've no choice because of how I'm handling their communication. Apart from this, I also created a new state simply just to allow them to communicate.
So far, this is still relatively manageable. But in my own experiment, it has got to a stage where I've children component nested inside another children components that need to communicate across other children components of the same (or sometimes different) level. Using states for communication also meant that I have many states all over the place, which doesn't look like a good idea to me. And the parent components ended up with tons of messy callback handler methods to manage all that propagation of data up and down the component tree.
The situation is so messy that I can at most illustrate it as something like so:
And you can see in the above illustration, ChildB ended up having yet another state just to help passing that information between its children components.
I'm sure I'm missing something that I should know about React. The callbacks I'm having in the parent components seem a little too much just to handle data propagation. How should I really organise the communication of children components in a clean and maintainable way?
Every React programmer hits this wall at some point in time. I did too. The answer is to use Redux for state management. You have experienced how tedious it is to use React's native state.
Redux is a state management mechanism which can be used in conjunction with React. So you won't be using React's state, instead you will use Redux.
Redux provides a single store, where the state of entire application is stored. You can access the state in your components using connect() method.
But there is a caveat. Not all of the react components are connected to the Redux store. There are two types of components-
Smart/connected components: Connected to redux store
Dumb components: Dependent on connected components
The idea is to pass the state from redux store to Connected components via React's props. The connected components can directly consume state from the store. The dumb components are not directly connected to the redux store. The connected components also pass the state to the dumb components via props. So you see, React's state is bypassed altogether. Now, if you want to change the state, following events must happen-
An event is fired from the smart/dumb component.
Actions are dispatched to the store
Reducers create a new state according to the actions.
A new state will be stored in the store.
Store will return new state to the connected components via connect() through props
Dumb components will receive new state from connected components through props
What are actions and reducers?
Actions are nothing but javascript objects that describe how to change the state.
Reducer is a "pure" function which builds and returns the new state tree according to the action dispatched to the store.
Redux - http://redux.js.org/
Redux-thunk - https://github.com/gaearon/redux-thunk
Redux-saga - https://github.com/yelouafi/redux-saga
Most fashion way is using Redux.js (or flux.js) to matain your child components state.
http://redux.js.org/
If you don't like invoke third party js. You can use refs property:
https://facebook.github.io/react/docs/more-about-refs.html
We can use the react context API,
Context provides a way to pass data through the component tree without having to pass props down manually at every level
Also, note that Mark Erikson has mentioned in his blog,
Yes, the new context API is going to be great for passing down data to deeply nested components - that's exactly what it was designed for.
If you're only using Redux to avoid passing down props, context could replace Redux - but then you probably didn't need Redux in the first place.
Context also doesn't give you anything like the Redux DevTools, the ability to trace your state updates, middleware to add centralized application logic, and other powerful capabilities that Redux enables.
To handle scenarios you mentioned, context API is a good option and you don't have to use additional libraries for that.

Categories