React Component calling method to a different component

Viewed 82

I have a page with the following structure

const Upload = (props) => {
    return (
        <BaseLayout>
            <ToolbarSelection />
            <Box>
                <FileDropArea />  
            </Box>           
        </BaseLayout>
    )
}

I have a method which works in the component <FileDropArea />

This is the method used as example

const allSelection = () => {
  setFiles((files) =>
    files.map((file) => {
      file.checked = true;
      return file;
    })
  );
};

In React how can i call this method allSelection from the <ToolbarSelection /> component, where i have my simple button like <Button>All Selection</Button>

3 Answers

You need to use React Context like this:

//create a fileContext.js 
const fileContext = React.createContext();
const useFileContext = () => React.useContext(fileContext);
const FileContextProvider = ({ children }) => {
  const [files, setFiles] = useState([]);

  const allSelection = () => {
    setFiles((files) =>
      files.map((file) => {
        file.checked = true;
        return file;
      })
    );
  };
  // if you have other methods which may change the files add them here
  return (
    <fileContext.Provider
      value={{
        files,
        setFiles,
        allSelection,
      }}
    >
      {children}
    </fileContext.Provider>
  );
};

use fileContextProvider in your upload file

const Upload = (props) => {
  return (
    <FileContextProvider>
      <BaseLayout>
        <ToolbarSelection />
        <Box>
          <FileDropArea />
        </Box>
      </BaseLayout>
    </FileContextProvider>
  );
};

use it, for example in ToolbarSelection like this:


const ToolbarSelection = () => {
  const {files, allSelection} = useFileContext();

  // do other stuff
}

React Hooks

I assume you are looking to make the allSelection function reusable. Hooks are a great way to make logic reusable across components.

Create a custom hook useAllSelection. Note that hooks should have a use prefix.

const useAllSelection = (files) => {
const [files, setFiles] = useState([]);

  const handleAllSelection = () => {
    setFiles((files) =>
      files.map((file) => {
        file.checked = true;
        return file;
      })
    );
  };

  return { handleAllSelection };
};
const ToolbarSelection = () => {
  // import the hook and use
  const { handleAllSelection } = useAllSelection();

  return (
    <button onClick={handleAllSelection}>All Selection</button>
  )
}

ReactJS allows to perform this scenario in a different way. Let me explain it: if you press a button in the ToolbarSelection, pass the value of the new state of that button to FileDropArea as props. Then, in the FileDropArea render, call the method or not depending on the value of that property

const Upload = (props) => {
    return (
        <BaseLayout>
            <ToolbarSelection 
                 onSelectionClick={(value) => setSelected(value)}
             />
            <Box>
                <FileDropArea 
                   selected = { /* state of a button in the Toolbar */}
                />  
            </Box>           
        </BaseLayout>
    )
}

Note how the callback in the Toolbar changes the state, and how this new state is passed to FileDropArea as property

Related