简体   繁体   English

React Hook useState 值被重置为初始值

[英]React Hook useState value being reset to initial value

The state of a value set using React useState hook gets set to the proper value and then reset to null.使用 React useState hook 设置的值的 state 被设置为正确的值,然后重置为 null。 Critical code below.下面的关键代码。 The click event that sets the startDate to the current date and time is 3 components down from where startDate is initialized.将 startDate 设置为当前日期和时间的单击事件是 startDate 初始化位置的 3 个组件。 When setStartDate did not work I created an arrow function, updateStartDate.当 setStartDate 不起作用时,我创建了一个箭头 function,updateStartDate。 Both had the same problem where the startDate was changed after the click event (witnessed per the console.log in the top component), but was null just before the next click event (per the console.log in the click event).两者都有相同的问题,即在单击事件之后更改了 startDate(根据顶部组件中的 console.log 见证),但在下一个单击事件之前是 null(根据单击事件中的 console.log)。 This is not an async problem as I see the change made before subsequent click.这不是异步问题,因为我看到在后续单击之前所做的更改。

If this is something that just does not work please explain.如果这不起作用,请解释。 I could probably fix with useReducer but prefer to keep the useState if there is something I can do to correct this... If not correctable then I would like to at least understand why it does not work so that I can avoid this problem in the future.我可能可以使用 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;

I renamed the component to BoardComponent and the state variable to boardLayout.我将组件重命名为 BoardComponent,并将 state 变量重命名为 boardLayout。 I included the full return portion of the BoardComponent below.我在下面包含了 BoardComponent 的全部返回部分。

As I am still experiencing the problem I would agree with you that, "DisplayTicTacToeContainer is being mounted twice".由于我仍然遇到这个问题,我同意你的观点,“DisplayTicTacToeContainer 正在安装两次”。 Any thoughts on how I can avoid this from happening?关于如何避免这种情况发生的任何想法?

Other than this inability to setStartDate, everything is working fine.除了无法设置开始日期外,一切正常。

//-----------------------------------------------
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;

At least, code below doesn't make much sense.至少,下面的代码没有多大意义。 Please don't set state value as a component.请不要将 state 值设置为组件。 Also, try to name state variable different from components, since it will confuse you at some ppint.此外,尝试将 state 变量命名为与组件不同的变量,因为它会使您在某些方面感到困惑。

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

 return (
        <Board/>
    )

Another possibility is that the DisplayTicTacToeContainer is being mounted twice, but I can't confirm it with the code provided.另一种可能性是DisplayTicTacToeContainer被安装了两次,但我无法使用提供的代码进行确认。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React useState hook 使用初始状态值并忽略更新 - React useState hook uses the initial state value and ignores the update 带有 useState 的自定义反应钩子始终重置为其初始值 - Custom react hook with useState always resetting to its initial value 尽管它被更新,但React useState钩子返回旧的状态值 - React useState hook returns old state value despite it being updated 在执行 useState 之前设置 useState 钩子的初始值 - Setting the initial value of a useState hook before useState is executed 反应 useState 不使用 new Date() 作为初始值 - react useState not working with new Date() as initial value 反应钩子是如何工作的? 为什么 useState 跟踪的值不会在重新渲染时重置? - How does react hook works? And how come the value tracked by useState does not reset on re-rendering? 无法将输入的值均衡到反应 useState Hook - Cant equalize value of input to a react useState Hook 如何在笑话和酶中为 useState Hook 设置初始状态值? - How to set initial state value for useState Hook in jest and enzyme? Hook 的 useState 初始值在被记忆的回调中永远不会改变 - Hook's useState initial value never changes in callback that is memoized 如何使用 Redux 商店中的 useState 挂钩设置初始值? - How to set initial value using useState hook from Redux store?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM