Reactjs 从 parent 更新状态来自 child 而没有 re-rendering parent

Reactjs updating state from parent came from child without re-rendering the parent

我是 reactjs 的初学者。现在我有优化我的 reactjs 项目的情况。我有一个来自 material-ui 的自动完成组件,我将它与我的 parent 组件分开,这样来自我的 auto-complete 的任何关键更改都不会导致 re-render 我的整个 parent成分。现在我的问题是关于将我的状态从我的 child 组件更新到 parent 组件,因为它 re-render 包括我的 parent 组件。关于如何避免 re-rendering 我的 parent 组件的任何提示?我的目标是不可能的场景吗? Suggestions/Answers 对像我这样的初学者表示赞赏,关于如何优化 passing/updating 我的状态从 child 到 parent。

我知道 setState 函数会导致 re-rendering。在我的 Parent 组件中,如何避免在 SearchTrainingData 函数中使用 setState 以便它可能不会 re-render 另一方面更新我的状态?我的 Parent 组件具有以下功能:

import SearchTraining from '../components/training/SearchTraining';

const Parent = () => {
    const SearchTrainingData = (index) => { 
    // console.log(index);   
    setState((prev) => ({
      ...prev,
      trainingTitle: index,
    }));
  };   
  
  return (
      <>
        <SearchTraining SearchTrainingData={SearchTrainingData} />
      </>
  )
  
}

这是我的 child 组件,它使用 props.SearchTrainingData 将我的更新状态从 child 传递到 parent 组件?

const SearchTraining = (props) => {

    const onChangeAutoComplete = (key, val) => {
        console.log(key);
        props.SearchTrainingData(val);        
      };

    return (
        <Autocomplete
        freeSolo
        disabled={
        selectedRecord && selectedRecord.conducted_training.locked
        }
        options={!selectedRecord ? state.trainingConductList : []}
        getOptionLabel={(option) =>
        option.title && option.title.title
            ? option.title.title
            : state.trainingTitle
        }
        getOptionSelected={(o, v) => o.id === v.id}
        value={state.training}
        renderOption={(option) => (
        <ListItemText
            primary={
            <>
                <Box>
                <Typography align="right">
                    <Button
                    onClick={() => {
                        setState((prev) => ({
                        ...prev,
                        newTrainingConduct: true,
                        isClicked: true,
                        }));
                    }}
                    >
                    Not what you&apos;re looking for?
                    </Button>
                </Typography>
                </Box>
                <Typography variant="body1" component="p">
                {option.title.title}
                </Typography>
            </>
            }
            secondary={
            <>
                <Box mt={1} mb={1}>
                <Typography
                    variant="body2"
                    component="p"
                    color="textSecondary"
                >
                    CONDUCTED BY:
                </Typography>
                <Typography
                    variant="overline"
                    component="p"
                    color="textPrimary"
                >
                    {option.conducted_by.name}
                </Typography>
                </Box>
                <Box mt={1}>
                <Typography
                    variant="caption"
                    color="textSecondary"
                    component="p"
                >
                    {option.from_date} - {option.to_date}
                </Typography>
                </Box>
                <Box mt={1} mb={1}>
                <Typography
                    variant="caption"
                    color="textSecondary"
                    component="p"
                >
                    Duration (hours): {option.total_hours}{' '}
                    {option.total_hours <= 1 ? ' hour' : ' hours'}
                </Typography>
                </Box>
                <Divider />
            </>
            }
        />
        )}
        onChange={(e, i) => {
        e.persist();
        if (i) {            
            onChangeAutoComplete('training', i);
        }
        }}
        />
    )
    
}

您可以使用 ref 而不是 state。使用 refs 可以避免在某些值更新后重新渲染组件。

在父组件中:

const ref=useRef(null)
const changeRef=(value)=>{ ref.current=value }

现在不是将状态和 setState 传递给 Child,而是传递 ref 并更改 Ref。 (或者您可以将 changeRef 放在 SearchTrainingData 中,这由您决定)

在子组件中:

const onChangeAutoComplete = (key, val) => {
    console.log(key);
    props.changeRef(val);        
  };

在自动完成中:

        value={props.ref.current}