在更新

时间:2015-07-29 13:11:38

标签: javascript reactjs

我有一个react组件,并且要求在更新渲染之前设置setState(url hash changes)。以下是代码段:

componentConfig: function() {
   .....
   this.setState({rows: rows});  
   this.setState({loadMoreBtn: loadMoreIsVisible})
},   

我以前工作过,我从getInitialState调用这个方法,它运行正常。 getInitialState只触发一次,因此我无法在网址更改时更新它。我尝试了各种其他内置更新方法,例如componentWillReceiveProps,但它们落后了一步。看起来像渲染在调用此方法之前发生。我也尝试从render调用它,但显然状态变得混乱而且它会中断。

enter image description here

如图所示,componentRillReceiveProps总是在渲染后面。我需要在每次在url更新时渲染之前触发的内容。希望它有意义。

或者换句话说,我想在哈希变化上解雇getInitialState

   var React = require('react'),
    projectsData = require('./../projects'),
    ProjectsRow = require('./projects_row'),
    itemsInRow = 3,
    noOfDefaultRows = 2,
    projects = [],
    currentProjects = [],
    currentPageRows,
    currentParamKey;

var Projects = React.createClass({

    componentWillMount: function() {
        this.componentConfig(this.props);
    }, 

    componentWillReceiveProps: function(nextProps){
        this.componentConfig(nextProps);
    },

    componentConfig: function(props) {
        var rows = [],
            currentParamKey = 'projects',
            loadMoreIsVisible = true,
            i; 

        if(props.params.key) {
            currentParamKey = props.params.key;
        }   

        projects = projectsData.getByKey(currentParamKey);      
        projectsData.currentState[currentParamKey] = noOfDefaultRows;       
        currentProjects = projects.slice(); //Create a copy or array 
        noOfDefaultRows = projectsData.currentState[currentParamKey] || noOfDefaultRows;    

        for (i = 0; i < noOfDefaultRows; i++) {
            if(currentProjects.length) {
                rows.push(currentProjects.splice(0, itemsInRow));
            } 
        }  

        currentProjects.length ? loadMoreIsVisible = true : loadMoreIsVisible = false;

        this.setState({rows: rows});  
        this.setState({loadMoreBtn: loadMoreIsVisible})

        console.log('Finished executing componentConfig and currentParamKey = ' ,currentParamKey);
    },

    loadMoreProjects: function(e) {

        e.preventDefault();
        var addRow = this.state.rows;

        if(currentProjects.length) {
            currentPageRows++;
            addRow.push(currentProjects.splice(0, itemsInRow));
            this.setState({rows: addRow});  
        } 

        if(!currentProjects.length) {
            this.setState({loadMoreBtn: false})
        }   
    },

    render: function() {

        console.log('Now in render and currentParamKey = ' ,currentParamKey);

        var projectUrl;

        //currentParamKey = this.props.params.key;

        if(currentParamKey === 'projects') {
            projectUrl = '#/project';
        } else {
            projectUrl = '#/project/' + currentParamKey
        }   

        return (
            < div className="projects">
                < div className = "jumbotron" >
                    < div className = "container" >
                        < h1 > Projects < /h1> 
                    < /div> 
                < /div>

                < div className = "container" >

                    {this.state.rows.map(function(row, i) {
                        return <ProjectsRow url={projectUrl} row={row} key={i} />
                    }.bind(this))}

                < /div> 

                < div className = "container text-center" > 
                    <a id="loadMore" className= {this.state.loadMoreBtn ? 'linkStyle1' : 'hide'} 
                        onClick = {this.loadMoreProjects}
                        role="button" > <i className="fa fa-angle-down"></i><span>Load More Projects</span> 
                    </a>
                    <br />
                    <br />

                    <div className="contact-me-link">
                        <a className="linkStyle1" href="#/contact">
                            <i className="fa fa-angle-right"></i><span>Contact</span>
                        </a>
                    </div>
                </div>
            < /div>
        );  
    }
});

module.exports = Projects;

1 个答案:

答案 0 :(得分:7)

componentWillReceiveProps将新道具作为参数。旧方法在此方法执行时保持不变,因此您需要根据此参数初始化状态。尝试将props作为参数传递给componentConfig方法:

componentWillMount: function() {
    this.componentConfig(this.props);
}, 
componentWillReceiveProps: function(nextProps){
    this.componentConfig(nextProps);
},
componentConfig: function(data) {
    ...
}