【问题标题】:Render Happening Before ComponentWillMount渲染发生在 ComponentWillMount 之前
【发布时间】:2018-04-16 14:27:41
【问题描述】:

我正在尝试在 ReactJs 中渲染我的组件之前加载一些初始数据。 我也在为这个过程使用Flux 架构。这是我的container

class MemoryApp extends React.Component {
    constructor(props){
        super(props);
        MemoryActions.getInit();
        this.state = {};

    }

    componentWillMount(){
        MemoryStore.on("init", () => {
            this.setState({
                memory: MemoryStore.getInit()
            });
        })
    }

    render(){
        return (
            <div>
                <button type="button">Get Random Memory</button>
                <h1>Memory App</h1>
                <MemoryImage memory={this.state.memory}/>
                <MemoryText memory={this.state.memory}/>
            </div>
        );
    }
}

所以在这个文件中,我调用了动作getInit(),它调用了一个API来获取一些数据。一旦收到此数据,init 事件将由store 发出:

class MemoryStore extends EventEmitter {

    getInit(){
        return this.memory_response;
    }

    initLoad(response){
        this.memory_response = response;
        this.emit("init");
    }

    handleActions(action){

        switch (action.type) {
            case MemoryConstants.GET_INIT_RESPONSE:{
                this.initLoad(action.response);
                break;
            }
            default:{
                return true;
            }
        }
    }

}

const memoryStore = new MemoryStore();
dispatcher.register(memoryStore.handleActions.bind(memoryStore));
export default memoryStore;

然后,如您所见,我们随后在componenWillMount() 中设置了状态。然后我想渲染组件。其中一个组件是image: 从“反应”导入反应

export default class MemoryImage extends React.Component{
    renderItems(){

        console.log(this.props); // ===> Here is my console.log
        if (this.props.memory){
            return this.props.memory[0].description;
        } else {
            return "Nothing";
        }
    }

    renderImage(){
        if (this.props.memory){
            return this.props.memory[0].image;
        } else {
            return "Nothing";
        }
    }

    render(){
        return(
            <div>
                <p>{this.renderItems()}</p>
                <img style={{width:'200px'}} src={this.renderImage()} alt="none"/>
            </div>
        );
    }
}

登录控制台后...

memory-image.js:10 {memory: undefined}
memory-image.js:10 {memory: Array(1)}

在我看来,组件是在我在 componentWillMount() 函数中设置状态之前呈现的。我不想要这个,我只希望在componentWillMount() 中设置状态后渲染组件。有什么想法吗?

【问题讨论】:

    标签: javascript reactjs reactjs-flux


    【解决方案1】:

    是的,它被渲染了,因为在组件挂载之前,你只需添加一个事件监听器:

    MemoryStore.on("init", () => {
        this.setState({
            memory: MemoryStore.getInit()
        });
    })
    

    返回(在事件之前)和渲染的函数。

    最简单的解决方案 (IMO) 是:

    getMemoryItems() {
        if (this.state.memory) {
            return <div>
                <MemoryImage memory={this.state.memory}/>
                <MemoryText memory={this.state.memory}/>
            </div>
        }
    }
    
    render(){
        return (
            <div>
                <button type="button">Get Random Memory</button>
                <h1>Memory App</h1>
                { this.getMemoryItems() }
            </div>
        );
    }
    

    或者你可以这样做:

    render(){
        return (
            <div>
                <button type="button">Get Random Memory</button>
                <h1>Memory App</h1>
                { this.state.memory ? <MemoryImage memory={this.state.memory}/> : '' }
                { this.state.memory ? <MemoryText memory={this.state.memory}/> : '' }
            </div>
        );
    }
    

    【讨论】:

      【解决方案2】:

      原因是您只在componentWillMount 中注册了一个事件处理程序,该事件将在将来某个时间发生时调用(即在您的情况下为init)。 componentWillMount 只会注册它并继续它的流程(即调用render 函数等)。只有当该事件被触发时,您才会获得memory 状态。

      因此,如果您不想在memory 状态可用之前渲染任何内容,那么您可以像这样简单地在渲染中放置一个条件

      render(){
              if(!this.state.memory){
                 // Just wait for the memory to be available
                 return null;
              }
              return (
                  <div>
                      <button type="button">Get Random Memory</button>
                      <h1>Memory App</h1>
                      <MemoryImage memory={this.state.memory}/>
                      <MemoryText memory={this.state.memory}/>
                  </div>
              );
          }
      

      【讨论】:

        猜你喜欢
        • 2018-04-05
        • 1970-01-01
        • 2017-06-30
        • 1970-01-01
        • 2021-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-21
        相关资源
        最近更新 更多