代码之家  ›  专栏  ›  技术社区  ›  mohsinulhaq

属性更改时反应组件重新呈现

  •  2
  • mohsinulhaq  · 技术社区  · 7 年前

    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>

    当我改变我作为道具传递给它的对象时,为什么不重新发送应用程序组件呢?

    每当我关闭并重新打开react dev工具时,它就会显示新的特性。 enter image description here

    这里发生了什么?请帮助我理解。

    谢谢!

    2 回复  |  直到 7 年前
        1
  •  3
  •   nanobar    6 年前

    在这种情况下,答案与setstate无关。当然,当状态发生变化时,react会自动重新呈现(只要您没有使用purecomponent之类的操作,然后改变数组或对象)。但是您正在从根进行渲染,这与react状态无关,因为您的状态存在于react之外。

    来自 react docs on render :

    如果以前将react元素呈现到容器中,则 对其执行更新,并且只在必要时改变DOM 反映最新的反应元素。

    所以需要在根级别再次调用render,以便作出反应来协调更改。另外,制作新的对象/数组也是更好的做法。所以在这种情况下你可以 x = x.concat(..) 然后再渲染。

    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);
    

    小提琴: https://jsfiddle.net/ferahl/p7zhs55q/1/

    当然,更常见的事情是在react组件中使用本地react状态,但是了解这一点是很好的,这就是如果您不使用redux之类的东西,那么如何实现某些全局状态以进行react。

        2
  •  2
  •   trixn    7 年前

    改变作为props传递的数据不会触发组件的重新呈现。没有观察者注意到你在那个可能触发它的物体上的突变。如果您有在组件生命周期中更改的数据 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,
        };
    
        componentDidMount() {
            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'));
    

    此代码将使用通过props传递的查询初始化组件状态。当组件装入后,它将开始间隔,该间隔将向状态附加一个新的随机数。打电话 setState() 将触发用新状态重新呈现。不要改变道具。