У меня есть компонент-ответчик, и требование заключается в установкеState перед рендером при обновлении (изменение хэша URL-адреса). Ниже приведен фрагмент кода:responsejs setState перед рендерингом при обновлении
componentConfig: function() {
.....
this.setState({rows: rows});
this.setState({loadMoreBtn: loadMoreIsVisible})
},
я это работает, прежде чем я был вызвать этот метод из getInitialState
и работает нормально. getInitialState
срабатывает только один раз, поэтому я не смог обновить его при изменении URL. Я пробовал различные другие встроенные методы обновления, такие как componentWillReceiveProps
, но они на один шаг позади. Кажется, что рендеринг происходит до вызова этого метода. Я также попытался назвать это от render
, но, очевидно, состояние запутывается и ломается.
Как показывает этот образ, 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;
componentWillReceiveProps должен работать перед следующим циклом рендеринга. Не могли бы вы опубликовать немного больше кода, чтобы дать нам лучшее представление о том, что вы делаете? – noveyak
Заметили ли вы, что компонент componentWillReceiveProps даст новое состояние в качестве аргумента, так что это только this.state, что на один шаг назад? – Seppo420
Добавлен код –