How to fix this state management and improve conditional rendering of react elements

I'm pretty dang new to react, and I'm trying to understand general best practices for state management, especially when state conditionally renders different react elements. I am looking for general best practices on how to properly structure the below code in order to manage state effectively and properly conditionally render my page's content.

Below is a quick code snippet showing how I am getting information about an "upstream" element, and using that information to conditionally render different form options in a "downstream" element. The general idea is that based on the type of document the user uploads, that then determines the different settings options they have available to them. I can tell that I'm writing spaghetti code, but I'm not sure how to refactor it/reorganize the code to make it cleaner. Below is a code snippet showing how I conditionally render different elements based on the fileType stored in inputType.

<div className="card-body" style={{ padding: "10px" }}>
          {(inputType === 'txt' || inputType === 'docx') && <TextExtractHandler id ={id} />}
          {inputType === 'image' && <div>Image Input Handler Placeholder</div>}
          {inputType === 'video' && <div>Video Input Handler Placeholder</div>}
          {(inputType === 'csv' || inputType === 'xlsx') && <div>Spreadsheet Input Handler Placeholder</div>}
        </div>

Here is my approach for getting the information from the upstream element, and how I use that information to update the state of the downstream element. This downstream element then uses that information to conditionally render the card object shown above.

const dispatch = useDispatch();
const nodeSettings = useSelector(state => state.nodeList.nodes.find(node => node.id === id)?.settings || {});
const [inputType, setInputType] = useState(nodeSettings.inputType || 'txt');

useEffect(() => {
    if (nodeSettings.inputType !== inputType) {
      dispatch(updateNodeSettings(id, { inputType }));
    }
  }, [inputType, nodeSettings.inputType, id, dispatch]);

// logic to get incoming content

  const selectNodeById = (state, nodeId) => {
    return state.nodeList.nodes.find((node) => node.id === nodeId);
  };

  const updateIncomingContent = useCallback((inputContent) => {
    if (node && nodes){
      console.log('Updating incoming content:', inputContent);
      dispatch(updateNodeSettings(id, { inputType, inputContent }));
    }
  }, [dispatch]);

  // Use useSelector with the selector function and the id prop
  const node = useSelector((state) => selectNodeById(state, id));
  const nodes = useSelector((state) => state.nodeList.nodes);
  const edges = useSelector((state) => state.edgeList.edges);

  //variables for viewport content change on incomers
  const [prevContent, setPrevContent] = useState(null);
  const [prevInput, setPrevInput] = useState(null);

  useEffect(() => {
    if (node && nodes && edges) {
      const incomers = getIncomers(node, nodes, edges);
      console.log('Incomers:', incomers);

      let inputContent = null;

      if (incomers.length > 0) {
        const firstIncomerId = incomers[0].id;
        const inputNode = nodes.find(n => n.id === firstIncomerId);
        if (inputNode && inputNode.dataContent !== null) {
          setInputType(inputNode.dataLabel);
          inputContent = inputNode.dataContent;
        }
      }

      if (inputContent !== prevContent || inputContent === null) {
        console.log('Input Content 222:', inputContent);
        setPrevContent(inputContent);
      }

      if (inputType !== prevInput || inputType === null) {
        console.log('Input Type 222:', inputType);
        setPrevInput(inputType);
      }
    }
  }, [node, nodes, edges, prevInput]);

  useEffect(() => {
    if (node && nodes){
      if (prevContent !== null || prevContent === null || prevInput !== null || prevInput === null) {
        updateIncomingContent(prevContent);
      }
    }
  }, [prevContent, updateIncomingContent]);
  
Вернуться на верх