Повторно используемый компонент контейнера с состоянием и динамическим дочерним компонентом

#reactjs

#reactjs

Вопрос:

Я пытаюсь создать повторно используемый компонент, который может создавать экземпляр динамического компонента:

 function EditableElement({endpoint, data, ElementFormClass}) {
    const [edit, setEdit] = useState(false);
    const [formData, setFormData] = useState(data);
    const [deleted, setDeleted] = useState(false);

    if (deleted) return (<p>X_X</p>);

    if (edit) return ElementFormClass(
        endpoint,
        data,
        setFormData,
        pk => {
            setDeleted(true);
        },
        e => setEdit(false)
    )

    return (
        <p onClick={e => setEdit(true)}>{formData.name}</p>
    )
}

function ElementFormDisplayOne({endpoint, data, cancel, updateData, deleteData}) {
    const [formData, setFormData] = useState(data);
    // const [deleted, setDeleted] = useState(false);
    // if (deleted) return (<p style={{color: 'red'}}>DELETED</p>);
    return (
        <form onSubmit={e => {
            e.preventDefault();
            e.stopPropagation();
            updateData(formData);
            cancel();
        }}>
            <label htmlFor={formData.pk}>{formData.name}</label>
            <input type="text" id={formData.pk} value={formData.name}
                   onChange={e => setFormData({...formData, name: e.target.value})}/>
            <button type="button" onClick={cancel}>cancel</button>
            <button type="submit">ok</button>
            <button type="button" onClick={e => deleteData(formData.pk)}>delete</button>
        </form>
    )
}
  

Он используется следующим образом:

 <div>
    <h3>Gallery Form ONE</h3>
    {data.map(el => <EditableElement endpoint={'update'} key={el.pk} data={el}
                                     ElementFormClass={ElementFormDisplayOne}/>)}
</div>
<div>
    <h3>Gallery Form TWO</h3>
    {data2.map(el => <EditableElement endpoint={'update'} key={el.pk} data={el}
                                      ElementFormClass={ElementFormDisplayTwo}/>)}
</div>
  

Но он выдает

Ошибка: отрисовано больше перехватов, чем во время предыдущего рендеринга.

Возможно ли то, что я хочу, в ReactJS? Примечание: я не использую Redux и не собираюсь

Пример Codesandbox

Комментарии:

1. Вы получите эту ошибку, когда перехват выполняется условно или когда он выполняется внутри цикла. Я не вижу ни одного случая в коде, который вы вставили до сих пор. Можете ли вы вставить больше кода в нижний блок кода, где он отображается <h3>Gallery Form ONE</h3> ?

2. @RossAllen Я отредактировал вопрос, чтобы включить пример codebox

Ответ №1:

Исправлена ошибка в строке 104 вашего codesandbox путем преобразования вашей функции в фактический элемент JSX.

 if (edit)
    return (<ElementFormClass
      endpoint={endpoint}
      data={data}
      setFormData={setFormData}
      cb1 = {(pk) => setDeleted(true)}
      cb2 = {(e) => setEdit(false)}
    />);
  

Это распространенная ошибка, с которой люди сталкиваются в react, где они используют компонент react как функцию, а не JSX.

Комментарии:

1. Ваше решение исправило ошибку, но я не понимаю, почему. У вас есть какой-либо ресурс, чтобы прочитать об этом? Кроме того, отмена / обновление / удаление не работают, не уверен, что это логическая ошибка.

2. да, ваше обновление, удаляющее материал, не сработает, потому что я дал несколько общих имен вашим обратным вызовам (cb1 и cb2).

3. Я более внимательно просмотрел код и теперь понимаю, в чем была моя ошибка. Спасибо!