Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

reactjs - State use as props in component, state change will not re-render the component

React will re-render if the state is changed. Then why the following situation cannot be re-render?

Base on the program behavior, I found that

  1. when state change, if the state is use directly in the component, it will be re-rendered.
  2. when state change, if the state is use as props in child component, it will not be re-rendered.
  3. how can I directly re-render that child component?

The following program is come from my code with some modification. Update: SandBox This is the code i created in sandbox, I have try to simulate my real situation

function List(props) {

    const [fullListValue, setFullListValue] = useState([]); //store data which get from server
    const [dropDrowList, setDropDrowList] = useState([]); //store data column value (e.g. data contain "fruit" column, this state will store "apple", "berry", "banana" etc.)

    const setAllList = (data) => {
        setFullListValue(data);
    };
    useEffect ( ()=> {
      //axios call server, use setAllList(data) to save state
    ,[]}

    //when fullListValue is updated, 
    useEffect(() => {
        const dropDrowListCopy = [{ ['label']: 'ALL', ['value']: 'ALL' }];
        //push all "fruit" data in dropDrowListCopy without duplicate
        console.log(dropDrowListCopy); //this will show all dropdown I want, i.e. "ALL","apple", "berry", "banana"
        setDropDrowList(dropDrowListCopy); //set to dropDrowList, and I expect this step will re-render the SelectionList component, however, it do not
    }, [fullListValue]);

    return (
        <div>
            <div>
                {dropDrowList.length <= 1 ? (
                    'loading'  //I add this to re-render the component, but I think this is not a good way to re-render the component
                ) : ( 
                    <SelectionList
                        itemList={dropDrowList}
                    />
                )}
            </div>
        </div>
    );
}
question from:https://stackoverflow.com/questions/65842049/state-use-as-props-in-component-state-change-will-not-re-render-the-component

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Issue

In SecitonList, you are storing passed props into state but not updating state when props change, leaving you with stale state. It's actually a React anti-pattern to store props in local component state for this reason.

Solution

Update state when props change.

function SelectionList(props) {
  const [listItem, setListItem] = useState(
    props.itemList ? props.itemList : []
  );

  useEffect(() => {
    setListItem(props.itemList);
  },
  [props.itemList]);

  return (
    <FormControl>
      <Select
        renderValue={
          props.multiple ? (selected) => fieldDisplay(selected) : null
        }
        input={<Input />}
      >
        {listItem.map((item) => (
          <MenuItem key={item.value} value={item}>
            {props.multiple ? (
              <Checkbox checked={selectedValue.indexOf(item) > -1} />
            ) : null}
            <ListItemText primary={item.label} />
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}

Solution - directly consume props

function SelectionList(props) {
  return (
    <FormControl>
      <Select
        renderValue={
          props.multiple ? (selected) => fieldDisplay(selected) : null
        }
        input={<Input />}
      >
        {props.itemList.map((item) => (
          <MenuItem key={item.value} value={item}>
            {props.multiple ? (
              <Checkbox checked={selectedValue.indexOf(item) > -1} />
            ) : null}
            <ListItemText primary={item.label} />
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...