Javascript 当 React 组件 prop 更改时如何获取数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39000698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fetch data when a React component prop changes?
提问by balu000
My TranslationDetail component is passed an id upon opening, and based on this an external api call is triggered in the class constructor, receiving data to the state, and this data being displayed on TranslationDetail.
我的 TranslationDetail 组件在打开时传递一个 id,并基于此在类构造函数中触发外部 api 调用,将数据接收到状态,并将此数据显示在 TranslationDetail 上。
//Routing:
<Route path="/translation/:id" component={TranslationDetail}/>
//Class:
class TranslationDetail extends Component {
constructor(props){
super(props);
this.props.fetchTrans(this.props.params.id);
}
This all works fine if I enter the url manually. In case I'd like to use react-router e.g. for displaying the next item like below the url does change, but the api call is not triggered, and the data will remain the same.
如果我手动输入网址,这一切都很好。如果我想使用 react-router 例如显示 url 下面的下一个项目确实会改变,但不会触发 api 调用,并且数据将保持不变。
<button
type="button"
onClick={() =>
browserHistory.push(`/translation/${Number(this.props.params.id)+1}`)}>
Next
</button>
Please bear in mind that I'm a total beginner. The reason why this is happening is I believe that the constructor is run only once, thus no further api call is triggered.
请记住,我是一个完全的初学者。发生这种情况的原因是我相信构造函数只运行一次,因此不会触发进一步的 api 调用。
How can I solve this? Do I need to listed to props and call a function on change? If yes, how?
我该如何解决这个问题?我是否需要列出道具并在更改时调用函数?如果是,如何?
回答by Yury Tarabanko
Constructor is not a right place to make API calls.
构造函数不是进行 API 调用的正确位置。
You need to use lifecycle events:
您需要使用生命周期事件:
componentDidMount
to run the initial fetch.componentDidUpdate
to make the subsequent calls.
componentDidMount
运行初始提取。componentDidUpdate
进行后续调用。
Make sure to compare the props with the previous props in componentDidUpdate
to avoid fetching if the specific prop you care about hasn't changed.
componentDidUpdate
如果你关心的特定 props 没有改变,请确保将 props 与之前的 props 进行比较以避免获取。
class TranslationDetail extends Component {
componentDidMount() {
this.fetchTrans();
}
componentDidUpdate(prevProps) {
if (prevProps.params.id !== this.props.params.id) {
this.fetchTrans();
}
}
fetchTrans() {
this.props.fetchTrans(this.props.params.id);
}
}
回答by Kevin
From React 16.3 and onwards componentWillMount
, componentWillUpdate
and componentWillReceiveProps
are deprecated.
从阵营16.3及以后componentWillMount
,componentWillUpdate
和componentWillReceiveProps
被弃用。
You can use static getDerivedStateFromProps
and return a new state based on changes on props.
您可以使用 staticgetDerivedStateFromProps
并根据道具的变化返回一个新状态。
You don't have access to your this objects like props, so you cannot compare nextProps
with your current props
by nextProps.sth !== this.props.sth
. You can compare you prevState
value with nextProps
and return new value of state.
您无法像道具一样访问您的 this 对象,因此您无法nextProps
与当前的props
by进行比较nextProps.sth !== this.props.sth
。您可以将您的prevState
价值与nextProps
状态进行比较并返回新的价值。
Make sue you add UNSAFE_
to your current componentWillMount
and the other deprecated lifecyle methods for now.
确保UNSAFE_
您现在添加到当前componentWillMount
和其他已弃用的生命周期方法中。
回答by Jan Franz Palngipang
Use componentWillMountto get the data and set the state. Then use componentWillReceivePropsfor capturing update on the props.
使用componentWillMount获取数据并设置状态。然后使用componentWillReceiveProps来捕获 props 上的更新。
You can check the Component Specs and Lifecycle.
您可以查看组件规格和生命周期。
回答by Carlos
I would use the render method. If the data is not loaded I would render a loader spinner and throw the action that fetch de data. For that i usually use the stores. Once the store has de data from the api, mark the data as loaded, throw an event and let the component get the data from the store, replacing the loader spinner with your data representation.
我会使用渲染方法。如果未加载数据,我将呈现加载器微调器并抛出获取数据的操作。为此,我通常使用商店。一旦存储从 api 获取数据,将数据标记为已加载,抛出一个事件并让组件从存储中获取数据,用您的数据表示替换加载器微调器。