Как исправить это управление состоянием и улучшить условный рендеринг элементов react
Я довольно чертовски новичок в react, и я пытаюсь понять общие лучшие практики для управления состоянием, особенно когда состояние условно рендерит различные элементы react. Я ищу общие лучшие практики того, как правильно структурировать приведенный ниже код, чтобы эффективно управлять состоянием и правильно условно отображать содержимое моей страницы.
Ниже приведен быстрый фрагмент кода, показывающий, как я получаю информацию об элементе «вверх по течению» и использую ее для условного отображения различных опций формы в элементе «вниз по течению». Общая идея заключается в том, что на основе типа документа, загружаемого пользователем, определяются различные доступные ему параметры. Я могу сказать, что пишу спагетти-код, но не уверен, как его рефакторить/реорганизовать, чтобы сделать чище. Ниже приведен фрагмент кода, показывающий, как я условно отображаю различные элементы на основе типа файла, хранящегося в 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>
Вот мой подход к получению информации от вышестоящего элемента, и как я использую эту информацию для обновления состояния нижестоящего элемента. Затем этот нижележащий элемент использует эту информацию для условного рендеринга объекта карточки, показанного выше.
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]);