admin管理员组文章数量:1327945
import React from 'react';
import { render } from 'react-dom';
const x = [];
const App = props => <div style={styles}>{JSON.stringify(x)}</div>;
render(<App queries={x} />, document.getElementById('root'));
setInterval(x => x.push(Math.random()), 1000, x);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
import React from 'react';
import { render } from 'react-dom';
const x = [];
const App = props => <div style={styles}>{JSON.stringify(x)}</div>;
render(<App queries={x} />, document.getElementById('root'));
setInterval(x => x.push(Math.random()), 1000, x);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Why doesn't the App ponent rerender when I mutate the object that I passed to it as a prop.
Whenever I close and reopen React Dev Tools, it shows the new props.
What is happening here? Please help me understand.
Thanks!
Share Improve this question edited May 18, 2018 at 17:56 mohsinulhaq asked May 18, 2018 at 15:06 mohsinulhaqmohsinulhaq 1,1071 gold badge20 silver badges32 bronze badges 2- 2 You need to use reactjs/docs/react-ponent.html#setstate – ponury-kostek Commented May 18, 2018 at 15:09
- There's actually no ponent with the proper lifecycle or state management present with the snippet you provided. – ReyHaynes Commented May 18, 2018 at 15:26
2 Answers
Reset to default 3The answer in this case is not related to setState. Sure React will automatically re-render when state changes (as long as you didn't do something like use a PureComponent and then mutate the array or object). But you are doing a render from the root and this has nothing to do with react state as your state exists outside of react.
From the react docs on render:
If the React element was previously rendered into container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React element.
So would need to call render again at the root level for React to reconcile the changes. Also it's better practice to make a new object/array. So in this case you could do x = x.concat(..)
and then render again.
let x = [];
const App = props => <div>{props.queries.toString()}</div>;
const renderApp = (queries) => ReactDOM.render(<App queries={queries} />, document.getElementById('root'));
setInterval(() => {
x = x.concat(Math.random());
renderApp(x);
}, 1000);
Fiddle: https://jsfiddle/ferahl/p7zhs55q/1/
Of course the more usual thing is to use local react state inside react ponents but it's good to have an understanding of this, and this is how you could implement some global state into react if you weren't using something like redux.
Mutating the data that you pass as props does not trigger a re-render of the ponent. There is no observer that takes notice of your mutation on that object that could trigger it. In case you have data that changes during the lifetime of a ponent you need to use state:
import React, {Component} from 'react';
import { render } from 'react-dom';
const x = [];
class App extends Component {
state = {
queries: this.props.queries,
};
ponentDidMount() {
setInterval(
() => this.setState(state => ({queries: [...state.queries, Math.random()]}))
), 1000);
}
render() {
return <div style={styles}>{JSON.stringify(this.state.queries)}</div>;
}
}
render(<App queries={x} />, document.getElementById('root'));
This code will initialize the ponent state with the queries passed via props. When the ponent did mount it will start the interval which will append a new random number to the state. Calling setState()
will trigger a re-render with the new state. Never mutate props.
本文标签: javascriptReact component rerender on prop changeStack Overflow
版权声明:本文标题:javascript - React component re-render on prop change - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742224048a2435660.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论