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'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}
我是 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'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}