React Hook useState 值被重置为初始值

时间:2021-05-19 15:26:13

标签: javascript reactjs react-hooks initialization use-state

使用 React useState hook 设置的值的状态被设置为正确的值,然后重置为 null。下面的关键代码。将 startDate 设置为当前日期和时间的单击事件是从 startDate 初始化位置向下的 3 个组件。当 setStartDate 不起作用时,我创建了一个箭头函数 updateStartDate。两者都有相同的问题,即在单击事件之后更改 startDate(根据顶部组件中的 console.log 见证),但在下一次单击事件之前为 null(根据单击事件中的 console.log)。这不是异步问题,因为我看到在后续点击之前所做的更改。

如果这是行不通的,请解释。我可能可以使用 useReducer 进行修复,但如果我可以做些什么来纠正这个问题,我更愿意保留 useState...未来。

export const DisplayTicTacToeContainer = (props) => {
 const [startDate, setStartDate]= useState();
 const updateStartDate = (newDate) => {
   setStartDate(newDate);
 }
 useEffect (() => {
   setStartDate(null);
 }, []);

 useEffect(() => {
    console.log( "displayTicTacToeContainer useEffect for change of startDate = ", startDate)
  }, [startDate]);

 return (
      <DisplayTicTacToeMatch  arrayOfMatchingItems ={arrayOfMatchingItems}
        startDate={startDate} 
        setStartDate={setStartDate}
        updateStartDate={updateStartDate}          
      />);
}

//-----------------------------------------------
export const DisplayTicTacToeMatch = (props)  => {
 const   { startDate,
           setStartDate,
           updateStartDate,
           } = props;

 useEffect(() => {
  // Performs some prep and working fine.
 }, []);

 return (
    <TicTacToe
      startDate={startDate} 
      setStartDate={setStartDate}
      updateStartDate={updateStartDate}
    />
  );
}
//-----------------------------------------------
const TicTacToeContainer = (props) => {
 const { startDate,
         setStartDate,
         updateStartDate,
        } = props;

 const [board, setBoard] = useState(<Board 
     updateStartDate={updateStartDate}
     startDate={startDate} 
     setStartDate={setStartDate}/>);

 return (
        <Board/>
    )
}
export default TicTacToeContainer;

我将组件重命名为 BoardComponent,将状态变量重命名为 boardLayout。我在下面包含了 BoardComponent 的完整返回部分。

由于我仍然遇到这个问题,我同意你的说法,“DisplayTicTacToeContainer 被挂载了两次”。关于如何避免这种情况发生的任何想法?

除了无法设置开始日期外,一切正常。

//-----------------------------------------------
const Board = (props) => {
 const { updateStartDate,
         startDate,
         setStartDate,
    } = props;

    return (
        <>
        <Grid container maxwidth="lg" alignItems="center" spacing={1}>
            <Grid item xs={9}>
                <Grid container alignItems="center">
                    <Grid item xs={9}>
                        <Typography variant = "body1">                      
                        First select a square.  Once the "Inquiry" word or phrase appears below, find 
                        the correct response in the column on the right and select that buttton.  A correct
                        response will fill the square previously selected with an "O" or "X".
                        </Typography>
                        <div style={{ width: '100%' }}>
                    <Box
                        display="flex"
                        flexWrap="wrap"
                        p={1}
                        m={1}
                        bgcolor="background.paper"
                        css={{ maxWidth: 900 }}
                    >
                    <Box p={1} bgcolor="grey.300">
                        Inquiry : {inquiry}
                    </Box>
                    </Box>
                    <Box
                        display="flex"
                        flexWrap="wrap"
                        p={1}
                        m={1}
                        bgcolor="background.paper"
                        css={{ maxWidth: 900 }}
                    >
                    <Box p={1} bgcolor="grey.300">
                        Next move by : {currentPlayer}
                    </Box>

                    <Box p={1} bgcolor="grey.300">
                        {showStatus}
                    </Box>
                    </Box>
                    </div>
                    </Grid>

                </Grid>
                        <MyAux>
                            {boardLayout.map((row, rowId) => { 
            const columns = row.map((column, columnId) => (
    
                <Grid key={columnId} item>
                    <ButtonBase > 
                        <Paper
                            onClick={(e) => {
                                clickSquareHandler(e);
                                }}
                            elevation={4}
                            data-coord={rowId + ':' + columnId}
                            id={"Square" + rowId.toString() +  columnId.toString()}
                            className={classes.Paper}>
                            <Icon
                                className={classes.Icon}
                                style={{fontSize: 78}}>
                            </Icon>
                        </Paper>
                    </ButtonBase>
                </Grid>
                ));
                return (
                <Grid
                    key={rowId}
                    className={classes.Grid}
                    container
                    spacing={2}>
                    {columns}

                </Grid>)
           })}
                        </MyAux>
                        </Grid>

        <Grid item xs={3} >
        <Paper className={classes.paper}>
        <Typography variant = "body1">    
            Response Options
        </Typography>
            <ButtonGroup
            orientation="vertical"
            color="secondary"
            aria-label="vertical outlined secondary button group"
        >
            {responseChoices.map((choice) => (
                              
                <Controls.Button
                    key ={choice.value}  
                    text={choice.value}
                    variant="contained"
                    color = "secondary"
                    onClick={() => {
                    chooseChecker(choice);
                    }}
                    className={
                    response && response.value === choice.value ? "selected" : ""
                    }
                    disabled={!!selected[choice.value]}
                    fullWidth = "true"
                    size = "small"
                    />
                ))}
            </ButtonGroup>
            </Paper>
            </Grid>
            </Grid>
                </>
    )
}

BoardContainer.propTypes = {
    won: PropTypes.func,
    size: PropTypes.number
};

export default BoardContainer;

1 个答案:

答案 0 :(得分:0)

至少,下面的代码没有多大意义。 请不要将状态值设置为组件。 另外,请尝试命名与组件不同的状态变量,因为它会使您在某些 ppint 上感到困惑。

 const [board, setBoard] = useState(<Board 
     updateStartDate={updateStartDate}
     startDate={startDate} 
     setStartDate={setStartDate}/>);

 return (
        <Board/>
    )

另一种可能是 DisplayTicTacToeContainer 被挂载了两次,但我无法通过提供的代码进行确认。