react强制组件刷新
Note: As of React 16, componentWillReceiveProps()
is deprecated, meaning if you are using that version or higher in your project, this is not good advice for you.
注意:从React 16开始, componentWillReceiveProps()
已被弃用,这意味着如果您在项目中使用该版本或更高版本,这对您来说不是一个好建议。
In the React world, forcing a re-render is frowned upon. You should let the DOM take care of itself when React perceives changes to state
or props
. In order to follow these patterns, we sometimes have to do stuff that seems a little silly. Consider this scenario:
在React世界中,强制重新渲染是不受欢迎的。 当React感知到state
或props
变化时,您应该让DOM照顾自己。 为了遵循这些模式,有时我们不得不做一些看起来有些愚蠢的事情。 考虑这种情况:
We’ve got two components — a parent and a child. The parent makes an API call to fetch the user
. From that, we get things like name
, age
, favorite color
. We also get an id
from our database. We’ll pass that to our child component, which is also going to make an API call, with the user id. Awesome — lots of data coming into our app.
我们有两个部分-父母和孩子。 父级进行API调用以获取user
。 由此,我们得到诸如name
, age
, favorite color
。 我们还从数据库中获取了一个id
。 我们会将其传递给子组件,该子组件还将使用用户ID进行API调用。 很棒–大量数据进入了我们的应用程序。
Let’s say we are storing a list of shoes in the database. When the user changes their color preference, the server writes new data to the user’s shoe list. Great! Except, we aren’t seeing the new shoe list in our child component. What gives?
假设我们要在数据库中存储鞋子列表。 当用户更改其颜色首选项时,服务器会将新数据写入用户的鞋子列表。 大! 除此以外,我们在子组件中看不到新的鞋子列表。 是什么赋予了?
Side note: Of course we should just get the shoes from the call for the user — this is just a simplified explanation.
旁注 :当然,我们应该只从用户电话中获得鞋子-这只是一个简化的说明。
The short of it is that React will only update parts of the DOM that have changed. In this case, the props
we pass to the shoe component ( userId
) haven’t changed, so nothing changes in our child component.
简而言之,React将仅更新已更改的DOM部分。 在这种情况下,传递给鞋子组件( userId
)的props
没有改变,因此子组件没有任何变化。
The color preference for the user will update when we get back new information from the API — assuming we are doing something with the response after we update a user.
当我们从API取回新信息时,用户的颜色首选项将更新-假设我们在更新用户后正在对响应进行某些操作。
But as React sees no reason to update the shoe list, it won’t — even though on our server, the shoes are now different.
但是由于React认为没有理由更新鞋子列表,所以不会-即使在我们的服务器上,鞋子现在有所不同。
const UserShow extends Component {
state = {
user: {}
}
componentDidMount() {
this.fetchUser().then(this.refreshUser)
}
setNewColor = color => {
this.updateUser({color}).then(this.refreshUser)
}
refreshUser = res => this.setState({user: res.data.user})
render() {
const { user } = this.state;
return (
User name: {user.name}
Pick color:
{colors.map(color =>
this.setNewColor(color)} />)}
)}
)
}
}
Our ShoeList
is just going to be a list of shoes, which we’ll fetch from the server with the user’s id:
我们的ShoeList
只是一个鞋子列表,我们将从服务器上获取用户ID:
const ShoeList extends Component {
state = {
shoes: []
}
componentDidMount() {
this.fetchShoes(this.props.id)
.then(this.refreshShoeList)
}
refreshShoeList = res => this.setState({ shoes: res.data.shoes })
render() {
// some list of shoes
}
}
If we want the shoe component to grab the new list of shoes, we need to update the props we send to it. Otherwise it will see no need to refresh.
如果我们希望鞋子组件获取新的鞋子列表,则需要更新发送给它的道具。 否则,它将不需要刷新。
In fact, the way this is written, the ShoeList
would never refresh, as we are not dependent on props for rendering. Let’s fix that.
实际上,由于我们不依赖于渲染道具,因此ShoeList
永远不会刷新。 让我们修复它。
触发子组件重新渲染 (Triggering a child component to re-render)
To force the child component to re-render — and make a new API call — we’ll need to pass a prop that will change if the user’s color preference has changed.
为了强制子组件重新呈现(并进行新的API调用),我们需要传递一个prop,如果用户的颜色首选项已更改,该prop将会更改。
To do this, we’ll add a method into setNewColor
:
为此,我们将一个方法添加到setNewColor
:
[...]
setNewColor = color => {
this.updateUser({color}).then(res => {
this.refreshUser(res);
this.refreshShoeList();
})
}
refreshShoeList = () =>
this.setState({refreshShoeList: !this.state.refreshShoeList})
[...]
This is a simple switch we can flip. I’ve kept things as simple as possible, but in production we’d want to make sure that the color we’re setting is different than the color we had before. Otherwise, there will be nothing to update.
这是我们可以翻转的简单开关。 我已使事情尽可能简单,但在生产中我们要确保所设置的颜色与以前的颜色不同。 否则,将没有任何更新。
Now in the ShoeList
:
现在在ShoeList
:
componentWillReceiveProps(props) {
const { refresh, id } = this.props;
if (props.refresh !== refresh) {
this.fetchShoes(id)
.then(this.refreshShoeList)
}
}
If you pass only refreshShoeList
and then toggle based on that boolean, the component will just update forever and ever and ever.
如果仅传递refreshShoeList
,然后基于该布尔值进行切换,则该组件将永远永远更新。
We need to make sure the switch has flipped only once — so we’ll just check that the props coming in are different than the props we had before. If they are different, we’ll make a new API call to get the new list of shoes.
我们需要确保开关只拨动过一次-因此我们只需检查进入的道具是否与之前的道具不同即可。 如果它们不同,我们将进行新的API调用以获取新的鞋子列表。
And boom — our child component has been “forced” to update.
繁荣-我们的子组件已被“强制”更新。
componentWillReceiveProps (componentWillReceiveProps)
It’s worth taking just one more minute to review what’s going on in that last piece of code. In componentWillReceiveProps
we have our only opportunity to view new props as they are coming in and compare them with previous props.
仅花一分钟的时间来回顾最后一段代码中的情况,这是值得的。 在componentWillReceiveProps
中,我们只有一次机会可以查看新的道具即将出现并将它们与以前的道具进行比较。
Here we can detect changes (like in refresh
) and we can also make checks for new props (note, for instance, that refresh
is initially undefined
).
在这里,我们可以检测到更改(例如在refresh
),还可以检查新道具(例如,请注意, refresh
最初是undefined
)。
This React method is a very powerful way to manipulate and examine props
.
这种React方法是操纵和检查props
的非常有效的方法。
翻译自: https://www.freecodecamp.org/news/force-refreshing-a-react-child-component-the-easy-way-6cdbb9e6d99c/
react强制组件刷新