为什么在道具更改时不重新渲染组件?

时间:2019-06-13 13:24:05

标签: reactjs material-ui

我有一个问题,当props值更改时,render方法不会运行。我究竟做错了什么?我尝试使用componentwillrecieveprops,但它也没有运行。

ChildComponent:

 state = {
    data: this.props.populatedWords,
    allSelected: false,
    res: null,
    textAreaVal: null,
    editMode: new Array(this.props.populatedWords.length).fill(false),
    entityList: [],
    selectedEntity: [],
    parts: [],
    final: null,
    entityObject: null,
    sendToUpdateEntity: null,
    arr: JSON.parse(localStorage.getItem('intents'))[localStorage.getItem('intent')],
    selectedValue: null,
    textInput: "",
    token: JSON.parse(localStorage.getItem('user')).tokens.training
};



componentWillReceiveProps(nextProps) {
    console.log("i am called")
    // You don't have to do this check first, but it can help prevent an unneeded render
    if (nextProps.words !== this.state.data) {
        this.setState({ data: nextProps.words });
    }
}

render() {

    return (
        <Card className={classes.root} style={{maxWidth: '100%'}}>
            <NoRazmetkaDialog ref={this.dialog}/>
            <NoEntityDialog ref={this.dialogE}/>
            <HalfRazmetkaDialog ref={this.dialogHalf}/>
            <CardHeader action={<Grid container>
                <Grid item style={{display: 'flex'}}>
                    <Tooltip>
                        <FilterOptions updateSelected={this.updateSelectedValue}/>
                    </Tooltip>
                    <TextField variant="standard" style={{paddingTop: '10px'}} onChange={e => {
                        this.setState({textInput: e.target.value});
                    }}/>
                </Grid>
            </Grid>}/>
            <div className={classes.tableWrapper}>
                <Table className={classes.table} aria-labelledby="tableTitle">
                    <IntentTableHead data={this.state.data} updateAllSelected={this.updateAllSelected}
                                     allSelected={this.state.allSelected} updateData={this.updateData}
                                     sendToDialogflow={this.sendToDialogFlow} updateEntity={this.updateEntity}
                                     entityObject={this.state.entityObject}/>
                    <TableBody>
                        {this.state.data.map((val, i) => {
                            return (
                                <TableRow hover>
                                    <TableCell padding="checkbox">
                                        <Checkbox checked={this.state.data[i].checked}
                                                  onChange={this.addCheckedPhrase(i)}/>
                                    </TableCell>
                                    {!this.state.editMode[i] &&
                                    <TableCell onClick={this.changeEditMode(i)}>
                                        {val.word}
                                    </TableCell>}
                                    {this.state.editMode[i] &&
                                    <TableCell>
                                        <TextField
                                            multiline
                                            defaultValue={val.word}
                                            className={classes.textField}
                                            margin="none"
                                            variant="outlined"
                                            value={this.state.textAreaVal}
                                            onChange={e => this.handleChange(e, i, 'word')}
                                        />
                                        <Button onClick={this.changeEditMode(i)}>OK</Button>
                                    </TableCell>
                                    }
                                    <TableCell>
                                        {array[localStorage.getItem('intent')].display_name}
                                    </TableCell>
                                    {this.state.data[i].test === null &&
                                    <TableCell>
                                        Тестировать
                                    </TableCell>}
                                    {this.state.data[i].test !== null &&
                                    <TableCell>
                                        {this.state.data[i].test}
                                    </TableCell>}
                                    <TableCell>
                                        <Select value={this.state.data[i].entity}
                                                onChange={e => this.handleChange(e, i, 'entity')}
                                                inputProps={{name: "data"}}>
                                            {this.state.entityList.map((val, i) => {
                                                return (<MenuItem value={val} key={i}>{val}</MenuItem>)
                                            })}
                                        </Select>
                                    </TableCell>
                                    <TableCell>
                                        <Button onClick={this.updateIntent(i)}>Обучить</Button>
                                    </TableCell>
                                    <TableCell>
                                        <IconButton onClick={this.deleteRow(i)}>
                                            <ClearIcon/>
                                        </IconButton>
                                    </TableCell>
                                </TableRow>
                            );
                        })}
                    </TableBody>
                </Table>
            </div>
        </Card>
    );
}

父组件:

 render() {

    return (
        <div>
            <PositionedDialog ref={this.dialog} selectedWord={this.state.selectedWord} textAreaVal={this.state.textAreaVal} updateRes={this.updateRes}/>
            <IconButton variant="contained"
                        color="primary"
                        component={Link} to="/app/intent"
                        onClick={this.backToComponent}
            >
                <KeyboardArrowLeft/>
            </IconButton>
            <Paper>
                <Toolbar>
                    <Grid container alignItems="center">
                        <Grid item xs alignItems="center">
                            <TextField
                                fullWidth
                                onFocus
                                id="help"
                                InputProps={{
                                    disableUnderline: true
                                }}
                                value={this.state.textAreaVal}
                                onKeyPress={e => {
                                    if (e.key === 'Enter') {
                                        this.findSelectedText();
                                    }
                                }}
                                onChange={e => {
                                    this.setState({textAreaVal: e.target.value});
                                }}
                            />
                        </Grid>
                    </Grid>
                </Toolbar>
            </Paper>
            <Paper style={{marginTop: "20px", overflow: "hidden"}}>
                {this.state.generator > 0 && this.state.populatedWords !== null &&
                <IntentTable populatedWords={this.state.populatedWords}/>}
            </Paper>
        </div>
    );
}

this.state.data构成一个表。当我的this.props.words更新时,它不会向表中添加行。我发现问题出在这里。

3 个答案:

答案 0 :(得分:1)

this.state.data未在您的渲染方法中使用

答案 1 :(得分:0)

首先,我认为您应该使用getDerivedStateFromProps,因为componentWillReceiveProps已过时。 为了解决您的问题,关于componentWillReceiveProps,您似乎在将孩子的this.state.datanextProps.words进行比较,但在我看来,您要发送的内容是:<IntentTable populatedWords={this.state.populatedWords}/>,因此您的道具名称是populateWords。尝试更改此设置并保持最新状态!

答案 2 :(得分:0)

为避免使用生命周期方法,请不要将道具保存在子组件中。从状态中删除dataeditMode

在您的孩子的渲染器中直接访问道具

render() {
 const data = this.props.populatedWords;
 const editMode = new Array(this.props.populatedWords.length).fill(false);
 ...
}
相关问题