2

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:

enter image description here

Sweet Caramel
  • 206
  • 2
  • 11
  • Hello, the reason it adds the "+" sign to each column is because of this line ` { selectedColumn === colId ? : null}`, you're essentially conditionally rendering against all the columns you have. If you want to specify it for the current selected column, you'd have to specifically target in the onClick event handler. – Abdulrahman Ali Sep 01 '22 at 11:27
  • @AbdulrahmanAli I have target **props.column.colId** on **setSelectedColumn**. Or do you mean something else? – Sweet Caramel Sep 01 '22 at 14:32

2 Answers2

3

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>
    )
  }

 
vairaden
  • 154
  • 1
  • 3
  • Thanks for the answer. 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. I updated the post. – Sweet Caramel Sep 01 '22 at 11:12
3

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,
  };
}, []);

Gabriel d'Agosto
  • 416
  • 3
  • 12