In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)05/31 Report--
In this article Xiaobian for you to introduce in detail "what is the way to update components when props changes in React", the content is detailed, the steps are clear, and the details are handled properly. I hope that this article "what is the way to update components when props changes in React" can help you solve your doubts, following Xiaobian's ideas to slowly deepen, together to learn new knowledge.
When to use derived state
Let's first take a look at a more common requirement, a list of users, who can add and edit users when they click 'New'
Button users can enter a new user name in the input box; when the edit button is clicked, the edited user name is displayed in the input box, which the user can modify; and the user list is updated when the user clicks the OK button.
Class UserInput extends React.Component {state = {user: this.props.user} handleChange = (e) = > {this.setState ({user: {... this.state.user, name: e.target.value}});} render () {const {onConfirm} = this.props; const {user} = this.state; return ({onConfirm (user)}} > OK) } class App extends React.Component {state = {users: [{id: 0, name: 'bruce'}, {id: 1, name:' frank'}, {id: 2, name: 'tony'}], targetUser: {}} onConfirm = (user) = > {const {users} = this.state; const target = users.find (u = > u.id = user.id) If (target) {this.setState ({users: [... users.slice (0, users.indexOf (target)), user,... users.slice (users.indexOf (target) + 1)]});} else {const id = Math.max (. Users.map (u = > u.id)) + 1 This.setState ({users: [... users, {... user, id}]});} render () {const {users, targetUser} = this.state Return ({users.map (u = > ({u.name} {this.setState ({targetUser: u})}} > Edit))} {this.setState ({targetUser: {}})}} > New)}} ReactDOM.render (, document.getElementById ('root'))
After running, the effect is as follows:
Now click the 'Edit' and 'New' buttons, and the text in the input box will not switch, because when you click 'Edit' and 'Update', the props of UserInput changes but does not trigger an update of state. So you need to implement the props change to trigger the state update and add the code to the UserInput:
ComponentWillReceiveProps (nextProps) {this.setState ({user: nextProps.user});}
Or
Static getDerivedStateFromProps (props, state) {return {user: props.user};}
This enables UserInput to automatically update the state each time it receives a new props. But there is something wrong with this way of implementation.
Problems caused by derivative statu
First of all, let's clarify the two concepts of components: controlled data (controlled data lives) and uncontrolled data (uncontrollered data lives). Controlled data refers to the data passed into the component through props, which is affected by the parent component; uncontrolled data refers to the state completely managed by the component itself, that is, internal state (internal state). The derived state combines two kinds of data sources, and the problem arises when the two data sources conflict.
Question one
When modifying a user, click the'OK 'button, and the text in the input box becomes the text before the modification. For example, after I change 'bruce' to' bruce lee', the input box becomes' bruce', which we don't want to see.
The reason for this problem is that when you click OK, App will re-render,App and pass the previous user to UserInput as props. Of course, we can reset the targetUser to an empty object after each click, but once there are too many states, it is very difficult to manage.
Question two
Suppose that after the page is loaded, some data will be requested asynchronously and then the page will be updated. If the user has entered some text in the input box before the request to complete the page refresh, the text in the input box will be cleared as the page is refreshed.
We can add the following code to App to simulate an asynchronous request:
ComponentDidMount () {setTimeout (() = > {this.setState ({text: 'fake request'})}, 5000);}
The reason for this problem is that when the asynchronous request is completed, the App will re-render after the setState, and the componentWillReceiveProps of the component will be executed each time the parent component render, and the user passed in is an empty object, so the contents of the UserInput are cleared. GetDerivedStateFromProps is called more frequently and will be called every time the component render, so this problem also occurs.
To solve this problem, we can determine whether the newly passed user is the same as the current user in componentWillReceiveProps, and set state if it is different:
ComponentWillReceiveProps (nextProps) {if (nextProps.user.id! = = this.props.user.id) {this.setState ({user: nextProps.user});}}
A better solution
The uncertainty of derived data sources can lead to problems that should be avoided if each piece of data is managed by only one component. There are two implementations of this idea, one is that the data is completely managed by the parent component, and the other is that the data is completely managed by the component itself. The following are discussed separately:
Fully controlled component (fully controlled component)
The data of the component comes entirely from the parent component, and the component itself will not need to manage the state. Let's create a fully controlled version of UserInput:
Class FullyControlledUserInput extends React.Component {render () {const {user, onConfirm, onChange} = this.props; return ({onConfirm (user)}} > OK)}}
The method of calling FullyControlledUserInput in App is as follows:
. {this.setState ({targetUser: {id: targetUser.id, name: e.target.value}});}} onConfirm= {this.onConfirm} / >.
Now all the data in FullyControlledUserInput comes from the parent component, which solves the problem of data conflict and tampering.
Completely uncontrolled components (fully uncontrolled component)
The data of the component is completely managed by itself, so the code in componentWillReceiveProps can be removed, but the incoming props is retained to set the initial value of state:
Class FullyUncontrolledUserInput extends React.Component {state = {user: this.props.user} onChange = (e) = > {this.setState ({user: {... this.state.user, name: e.target.value}});} render () {const {user} = this.state; const {onConfirm} = this.props; return ({onConfirm (user)}} > OK)}}
When the incoming props changes, we can update the page by re-creating an instance of component by passing in a different key. The method of calling FullyUncontrolledUserInput in App is as follows:
In most cases, this is a better solution. Some people may think that the performance will be affected, but the performance will not slow down much, and if the logic of the component update is too complex, it is not as fast as to recreate a new component.
The method of calling the child component in the parent component sets the state
If there is no suitable attribute as key in some cases, you can pass in a random number or a self-increasing number as key, or we can define a method in the component to set state and expose it to the parent component through ref, for example, we can add to UserInput:
SetNewUserState = (newUser) = > {this.setState ({user: newUser});}
Call this method through ref in App:
. {users.map (u = > ({u.name} {this.setState ({targetUser: u}); this.refs.userInput.setNewUserState (u);}} > edit))} {this.setState ({targetUser: {}}); this.refs.userInput.setNewUserState ({});}} > New. After reading this, the article "what is the way to update components when props changes in React" has been introduced. If you want to master the knowledge of this article, you still need to practice and use it. If you want to know more about the article, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.