我有一个Dashboard组件,用于呈现从后端服务器获取数据的卡阵列。用户可以通过提交表单来创建其他卡片,然后将表单重定向回仪表板页面。
我的问题是,在提交表单时,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');
}
答案 0 :(得分:2)
与@JasonWarta提到的类似,值得注意的是,当false
,null
或undefined
被返回时,React不呈现任何内容,因此您通常可以使用&&
比使用条件(&#34;三元&#34;)运算符更简洁:
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
,并且该组件也不会呈现任何内容(与您返回{{时相同) 1}})。
答案 1 :(得分:0)
我在这种情况下使用过三元运算符。您可能需要调整模式的检查部分,具体取决于您的redux模式返回的内容。如果null
为假,则会返回this.props.cards
值。
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)}
>
</CardList>
</div>
:
null
}
);
}
答案 2 :(得分:0)
作为其他答案的替代方案,如果渲染函数中没有带if语句的数据,则可以返回其他合适的答案。我更喜欢像渲染之外的过滤器一样移动函数。也许另一种(更好的?)方法是在mapStateToProps函数中进行过滤。
另外,如果我没错,你不需要将任何东西传递给你的handleChange函数。因为您从CardList组件返回filterText然后设置状态。
cardList = () => this.props.cards.filter(card =>
card.title.includes(this.state.filterText.trim().toLowerCase()));
render() {
if ( !this.props.cards.length ) {
return <p>No cards</p>
// or return <SpinnerComponent />
}
return (
<div>
<CardList cards={this.cardList()}
handleChange={this.handleChange} />
</div>
);
}