首页 > 解决方案 > 如何防止组件在获取数据之前渲染子组件

问题描述

我有一个仪表板组件,它使用从后端服务器获取的数据呈现一组卡片。用户可以通过提交表单来创建其他卡片,然后将它们重定向回仪表板页面。

我的问题是,提交表单时,会抛出 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');
}

标签: javascriptreactjsreduxreact-reduxredux-form

解决方案


与@JasonWarta 提到的类似,值得注意的是,React 在 , 或 返回时不会呈现任何内容falsenull因此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>
  );
}

因为&&短路,后半部分不会被求值,所以你可以避免TypeErrors,并且组件也不会渲染任何内容(和你 return 时一样null)。


推荐阅读