简体   繁体   中英

useState doesn't update state passed in component

The SelectedColumn value doesn't come in the CustomHeader component. However, setSelectedColumn works? Why, Also, I'm passing CustomHeader to constant components that use useMemo. Without useMemo CustomHeader doesn't work.

  const [selectedColumn, setSelectedColumn] = useState(null);
  console.log("selected Column Outside:", selectedColumn); // It works!

  const CustomHeader = (props) => {
    const colId = props.column.colId;

    console.log("selected Column In CustomHeader:", selectedColumn); // Doesn't work
    return (
      <div>
        <div style={{float: "left",  margin: "0 0 0 3px"}} onClick={() => setSelectedColumn(props.column.colId)}>{props.displayName}</div>
        { selectedColumn === colId ? <FontAwesomeIcon icon={faPlus} /> : null}
      </div>
    )
  }

  const components = useMemo(() => {
    return {
      agColumnHeader: CustomHeader
    }
  }, []);

UPDATE: If I use the useState hook inside the CustomHeader component, it adds a "+" sign to each column and does not remove from the previous one. Here is a picture:

在此处输入图像描述

You should use hooks inside your component

  const CustomHeader = (props) => {
    const colId = props.column.colId;

    const [selectedColumn, setSelectedColumn] = useState(null); 

    console.log("selected Column In CustomHeader:", selectedColumn); // Should work
    return (
      <div>
        <div style={{float: "left",  margin: "0 0 0 3px"}} onClick={() => setSelectedColumn(props.column.colId)}>{props.displayName}</div>
        { selectedColumn === colId ? <FontAwesomeIcon icon={faPlus} /> : null}
      </div>
    )
  }

 

After reading your comment, your issue is clearly about where you want to place your useState.

First of all, you should always place useState inside a component. But in your case, apparently what you're trying to achieve is that when you select a column, the other columns get deselected.

Therefore, you need to pass both selectedColumn and setSelectedColumn as props to your component, and create the useState on the parent component.

Assuming all your CustomHeader components share the same parent component, in which my example I'll call CustomHeadersParent , you should do something like this:

// added mock headers to have a working example
const headers = [
  {
    displayName: "Game Name",
    column: {
      colId: 1,
    },
  },
  {
    displayName: "School",
    column: {
      colId: 2,
    },
  },
];

const CustomHeadersParent = (props) => {
  const [selectedColumn, setSelectedColumn] = useState(null);

  return headers.map((h) => (
    <CustomHeader
      column={h.column}
      displayName={h.displayName}
      setSelectedColumn={setSelectedColumn}
      selectedColumn={selectedColumn}
    />
  ));
};


const CustomHeader = (props) => {
  const colId = props.column.colId;

  return (
    <div>
      <div
        style={{ float: "left", margin: "0 0 0 3px" }}
        onClick={() => props.setSelectedColumn(props.column.colId)}
      >
        {props.displayName}
      </div>
      {props.selectedColumn === colId ? <FontAwesomeIcon icon={faPlus} /> : null}
    </div>
  );
};

const components = useMemo(() => {
  return {
    agColumnHeader: CustomHeader,
  };
}, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM