javascript - 如何防止组件在获取数据之前渲染子组件
问题描述
我有一个仪表板组件,它使用从后端服务器获取的数据呈现一组卡片。用户可以通过提交表单来创建其他卡片,然后将它们重定向回仪表板页面。
我的问题是,提交表单时,会抛出 javascript 错误“无法读取未定义的属性“包含””,并且仪表板不会呈现。如果我手动刷新页面,列表将按预期使用新卡呈现。我使用 Array.includes 方法根据 filterText 状态值过滤卡片。出现这个错误是因为调用render时没有获取数据吗?如果是这样,我如何强制组件等到有数据再渲染?请参阅下面的组件和 redux 操作。
const CardList = (props) => {
const cards = props.cards.map(({ _id, title}) => {
return (
<Card key={_id} title={title} />
)
});
return (
<div className="container">
<input onChange={ (e) => props.handleChange(e.target.value) } />
<div className="row">
{cards}
</div>
</div>
);
}
export default CardList;
export class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
filterText: ''
}
}
componentDidMount() {
this.props.fetchCards();
}
handleChange = (filterText) => {
this.setState({filterText});
}
render() {
const cardList = this.props.cards.filter(card =>
card.title.includes(this.state.filterText.trim().toLowerCase())
);
return (
<div>
<CardList cards={cardList}
handleChange={filterText => this.handleChange(filterText)} />
</div>
);
}
};
function mapStateToProps({ cards: { cards }}) {
return {
cards,
}
}
export default connect(mapStateToProps, {fetchCards})(Dashboard);
export class SurveyForm extends Component {
render() {
return (
<div>
<form>
<Field component={CardField} type="text"
label={'title'} name={'title'} key={'title'} />
<Button type="submit" onClick={() => submitCard(formValues, history)}>Next</Button>
</form>
</div>
);
}
}
REDUX ACTION DISPATCHER:
export const submitCard = (values, history) => async dispatch => {
const res = await axios.post('/api/cards', values);
try {
dispatch({ type: SUBMIT_CARD_SUCCESS, payload: res.data });
dispatch({ type: FETCH_USER, payload: res.data })
}
catch(err) {
dispatch({ type: SUBMIT_CARD_ERROR, error: err });
}
history.push('/cards');
}
解决方案
与@JasonWarta 提到的类似,值得注意的是,React 在 , 或 返回时不会呈现任何内容false
,null
因此undefined
您通常可以使用&&
比使用条件(“三元”)运算符更简洁:
render() {
return this.props.cards && (
<div>
<CardList
cards={this.props.cards.filter(card => card.title.includes(this.state.filterText.trim().toLowerCase())}
handleChange={filterText => this.handleChange(filterText)}
/>
</div>
);
}
因为&&
短路,后半部分不会被求值,所以你可以避免TypeError
s,并且组件也不会渲染任何内容(和你 return 时一样null
)。
推荐阅读
- javascript - THREE.js FBXLoader 将 .png 视为 .psd,并且不加载素材
- r - 类中的R Setter方法
- c++ - 变量值自动改变
- c++ - 如何使用堆分配进行运算符++重载
- firebase - 从包装 Express 应用程序的函数请求静态 *.js 文件时出现 502 错误
- javascript - 如何将脚本标签/JS作为文本附加到文本区域(不可执行)
- c++ - 逗号的左操作数无效 vs 逗号的右操作数无效
- formal-verification - 证明基本算术性质
- python - 重新训练 Mobilenet_SSD KeyError: 'eval_input_fns'
- python - 如何替换缺少的列值?