在 ComponentWillMount 之前渲染

Render Happening Before ComponentWillMount

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

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

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

函数 returns(在事件之前),并呈现。

最简单的解决方案 (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>
    );
}

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