反应 JS 组件 "wait for props"
React JS Component "wait for props"
这不是一个问题 "how to make this work" 而是一个 "was this the best way." 这是我的代码:
/**
* React Static Boilerplate
* https://github.com/koistya/react-static-boilerplate
* Copyright (c) Konstantin Tarkus (@koistya) | MIT license
*/
import React, { Component } from 'react';
// import './InputWidgetText.scss';
import ContentBlock from '../ContentBlock';
var i = 0;
var contentBlocks = [];
var ContentContainer = React.createClass({
addNewBlock: function(){
i++;
contentBlocks.push(<ContentBlock key={i} index={i}/>)
this.forceUpdate();
},
render: function(){
if (this.props.inputs) {
contentBlocks = this.props.inputs.map(function(item, index){
i++;
return(<ContentBlock key={index} index={index} content={item} />)
});
}
return (
<div>
{contentBlocks}
<button onClick={this.addNewBlock}>+</button>
</div>
)
}
});
export {ContentContainer as default};
问题是,在我尝试映射未定义时,props.inputs 经常在刷新时没有传递到此组件并抛出错误。所以简单的解决方案是将 map 进程放在 if 中,检查道具是否存在——这实际上是处理这个问题的正确方法吗?我的数据是通过父级上的回流混合器传入的。我只是觉得可能有更合适的方法来处理这个问题。感谢反馈!
我强烈建议您重构代码以消除文件变量 i
和 contentBlocks
.
contentBlocks
变量似乎完全没有必要,而您的 i
变量应该是 state 的一部分。当你这样做的时候,给 i
一个更有意义的名字,例如blockCount
.
getInitialState: function () {
return {
blockCount: 0
};
},
然后定义你的点击事件处理器来修改状态:
addNewBlock: function () {
this.setState({
blockCount: this.state.blockCount + 1
});
},
每次调用setState()
,React都会触发重新渲染。你永远不需要调用 forceUpdate()
.
最后,您的 render()
函数应该 return 其内容完全基于 this.props
和 this.state
。也就是说,对于任何给定的道具和状态,输出都是可预测的。将 this.props
和 this.state
视为 render()
函数的输入参数。这就是 render()
可以或需要知道的全部内容。
我不会尝试编写 render()
函数,因为我不确定您要使用此组件实现什么。但是对于给定的 this.props.input
和 this.state.blockCount
(或者你选择用作道具和状态的任何东西)你应该确切地知道你在输出什么。
我知道我还没有直接回答你提出的问题,但我希望这能澄清一些 React 概念。
这不是一个问题 "how to make this work" 而是一个 "was this the best way." 这是我的代码:
/**
* React Static Boilerplate
* https://github.com/koistya/react-static-boilerplate
* Copyright (c) Konstantin Tarkus (@koistya) | MIT license
*/
import React, { Component } from 'react';
// import './InputWidgetText.scss';
import ContentBlock from '../ContentBlock';
var i = 0;
var contentBlocks = [];
var ContentContainer = React.createClass({
addNewBlock: function(){
i++;
contentBlocks.push(<ContentBlock key={i} index={i}/>)
this.forceUpdate();
},
render: function(){
if (this.props.inputs) {
contentBlocks = this.props.inputs.map(function(item, index){
i++;
return(<ContentBlock key={index} index={index} content={item} />)
});
}
return (
<div>
{contentBlocks}
<button onClick={this.addNewBlock}>+</button>
</div>
)
}
});
export {ContentContainer as default};
问题是,在我尝试映射未定义时,props.inputs 经常在刷新时没有传递到此组件并抛出错误。所以简单的解决方案是将 map 进程放在 if 中,检查道具是否存在——这实际上是处理这个问题的正确方法吗?我的数据是通过父级上的回流混合器传入的。我只是觉得可能有更合适的方法来处理这个问题。感谢反馈!
我强烈建议您重构代码以消除文件变量 i
和 contentBlocks
.
contentBlocks
变量似乎完全没有必要,而您的 i
变量应该是 state 的一部分。当你这样做的时候,给 i
一个更有意义的名字,例如blockCount
.
getInitialState: function () {
return {
blockCount: 0
};
},
然后定义你的点击事件处理器来修改状态:
addNewBlock: function () {
this.setState({
blockCount: this.state.blockCount + 1
});
},
每次调用setState()
,React都会触发重新渲染。你永远不需要调用 forceUpdate()
.
最后,您的 render()
函数应该 return 其内容完全基于 this.props
和 this.state
。也就是说,对于任何给定的道具和状态,输出都是可预测的。将 this.props
和 this.state
视为 render()
函数的输入参数。这就是 render()
可以或需要知道的全部内容。
我不会尝试编写 render()
函数,因为我不确定您要使用此组件实现什么。但是对于给定的 this.props.input
和 this.state.blockCount
(或者你选择用作道具和状态的任何东西)你应该确切地知道你在输出什么。
我知道我还没有直接回答你提出的问题,但我希望这能澄清一些 React 概念。