渲染在ComponentWillMount之前发生

时间:2017-11-03 19:03:58

标签: javascript reactjs reactjs-flux

我试图在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: 从'react'中导入React

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()中设置状态后呈现组件。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

是的,它被渲染,因为在组件安装之前,您只需添加en事件侦听器:

    Error(36,9): PLS-00103: Encountered the symbol "FMILEAGEBALANCE" when   
    expecting one of the following:     . ( , % ; limit The symbol "." was   
    substituted for "FMILEAGEBALANCE" to continue. 

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

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

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

或者你可以这样做:

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

答案 1 :(得分:1)

原因是你只在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>
        );
    }