更新没有父级之外的react组件

IT技术 reactjs
2021-05-01 01:20:01

如果没有父组件,我应该如何正确更新组件?

我找到了两种方法:

第一种方法

这里我通过改变组件的状态来更新组件:

var Hello = React.createClass({
  render: function() {
    if (!this.state) return null;
    return (
      <div>Hello {this.state.name}</div>
    );
  }
});


var component = ReactDOM.render(
  <Hello />,
  document.getElementById('container')
);
component.setState({name: "World"});

setTimeout(function(){
  component.setState({name: "StackOverFlow"});
}, 1000);

第二种方法

这里我通过ReactDOM.render方法更新组件

var Hello = React.createClass({
  render: function() {
    return (
      <div>Hello {this.props.name}</div>
    );
  }
});


ReactDOM.render(
  <Hello name="world"/>,
    document.getElementById('container')
);

setTimeout(function(){
  ReactDOM.render(
    <Hello name="StackOverFlow"/>,
      document.getElementById('container')
  );

}, 1000);

那么哪种方法是正确的呢?或者也许这是第三种正确的方法?

3个回答

如果您只是想从组件外部触发重新渲染,则公开其 forceUpdate 方法。

初始 ReactDOM.render 返回对组件的引用,您可以使用它:

const component = ReactDOM.render(<MyComponent />)

component.forceUpdate()

这是一种反模式:如果你这样做,就不可能仅仅查看组件来推断组件的状态,这是 React 背后的哲学(据我所知)的一部分。

正确的方法是修改props组件的 ,它可以通过componentWillReceiveProps在渲染之前设置一个新状态来对 prop 变化做出react

class MyComponent extends React.Component {
  componentWillReceiveProps (nextProps) {
    if(make sure that props have actually changed) { // https://facebook.github.io/react/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html
      this.setState({
        // set your new state using some calculation based on the props
        // this will not result in an extra render
      });
    }
  },
  render () {
    return <div>Hello {this.state ? this.state.name : "Loading..."}</div>;
  }
}

ReactDOM.render理想情况下,应仅在应用程序引导时调用一次调用如果你看到自己不止一次地调用它,你可能做错了一些事情。

至于如何做事的确切建议,这取决于您拥有的项目和/或架构的类型。

如果您刚刚开始尝试 React 并且还没有决定 100% 使用 Flux 架构(有点高级主题),我发现开始构建东西非常有用。

您唯一需要记住的是,一段数据存放在哪里?state, props, 或即时计算?

答案取决于很多东西,但通常情况下,最好尽可能多地即时计算数据,将东西放入props中,作为最后的手段,将东西放入状态。

这是一个人为的例子:

//client.js
const render = require('react-dom').render;
const App = require('./components/App.jsx');

render(<App />, document.querySelector('#app-container'));


//components/App.jsx
const React = require('react');
const request = require('superagent');

module.exports = React.createClass(
    displayName: 'HelloUserApp',

    getInitialState() {
        return {
            firstName: null,
            lastName: null
        };
    },

    componentDidMount() {
        this.setState({
            isFetchingName: true
        });

        request.get('/users/self')
               .end((err, res) => {
                   this.setState({isFetchingName: false});
                   this.setState(res.user);
               });
    }


    render() {
        return (
            <div className="greeting">
                {this.state.isFetchingName ? 'Loading...' : this.state.firstName + ' ' + this.state.lastName}
            </div>
        );

    }
);