如果组件没有父组件,我应该如何正确更新组件?
我找到了两种方法:
这里我通过改变组件的状态来更新组件:
var Hello = React.createClass({
render: function() {
if (!this.state) return null;
return (
<div>Hello {this.state.name}</div>
);
}
});
var component = ReactDOM.render(
<Hello />,
document.getElementById('container')
);
component.setState({name: "World"});
setTimeout(function(){
component.setState({name: "StackOverFlow"});
}, 1000);
这里我通过ReactDOM.render
方法更新组件:
var Hello = React.createClass({
render: function() {
return (
<div>Hello {this.props.name}</div>
);
}
});
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('container')
);
setTimeout(function(){
ReactDOM.render(
<Hello name="StackOverFlow"/>,
document.getElementById('container')
);
}, 1000);
那么哪种方法是正确的?或者这可能是第三种正确的方式?
答案 0 :(得分:4)
如果您只是想从组件外部触发重新渲染,则会暴露其forceUpdate方法。
最初的ReactDOM.render返回对组件的引用,您可以使用它:
var properties = {};
if(command == "/set"){
var property = prompt("Property:");
var value = prompt("Set to:");
if (properties.hasOwnProperty(property) {
properties[property] = value;
} else {
alert("Property Doesnt Exists")
}
}
答案 1 :(得分:1)
它是一种反模式:如果你这样做,就不可能仅仅看到组件的组件状态,这是React背后的哲学(我理解)的一部分。
正确的方法是修改组件的props
,它可以通过在呈现之前在componentWillReceiveProps
内设置新状态来对道具更改做出反应:
class MyComponent extends React.Component {
componentWillReceiveProps (nextProps) {
if(make sure that props have actually changed) { // https://facebook.github.io/react/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html
this.setState({
// set your new state using some calculation based on the props
// this will not result in an extra render
});
}
},
render () {
return <div>Hello {this.state ? this.state.name : "Loading..."}</div>;
}
}
答案 2 :(得分:0)
理想情况下调用ReactDOM.render
只应在应用程序引导时调用一次。如果你看到自己多次调用它,你可能会做一些“错误”的事情。
至于如何做事的确切建议,取决于你拥有的项目类型和/或架构。
如果您刚刚开始尝试使用React并且尚未100%确定您将使用Flux架构(有些高级主题),我发现开始构建时非常有用。
您需要记住的唯一事项是,一段数据存在于何处? state
,props
或动态计算?
答案取决于很多东西,但通常情况下,最好尽可能快地计算数据,把东西放在道具中,作为最后的手段,把东西放在州里。
这是一个人为的例子:
//client.js
const render = require('react-dom').render;
const App = require('./components/App.jsx');
render(<App />, document.querySelector('#app-container'));
//components/App.jsx
const React = require('react');
const request = require('superagent');
module.exports = React.createClass(
displayName: 'HelloUserApp',
getInitialState() {
return {
firstName: null,
lastName: null
};
},
componentDidMount() {
this.setState({
isFetchingName: true
});
request.get('/users/self')
.end((err, res) => {
this.setState({isFetchingName: false});
this.setState(res.user);
});
}
render() {
return (
<div className="greeting">
{this.state.isFetchingName ? 'Loading...' : this.state.firstName + ' ' + this.state.lastName}
</div>
);
}
);