useReducer для редактирования форм с сопоставленными данными

avatar
JustinMcDonald
1 июля 2021 в 18:13
152
1
0

Хорошо, все вы, профессионалы React. Я уже некоторое время пытаюсь обдумать это. У меня есть база данных с массивом объектов, внутри которых есть вложенные массивы.

Исходное состояние выглядит примерно так...

const initialState = [{

    id: '',
    mainContent:[ 
        {
            title: "",
            content: []            
        },       
    ],            
    sideContent:[ 
        {
            title: "",
            content: []
        },       
    ],        
    pageTitle: ""

}]

С некоторым содержанием это что-то вроде

const initialState = [{

    id: '123',
    mainContent:[ 
        {
            title: "About",
            content: ['something', 'something else', 'other stuff', 'blah blah blah']            
        }, 
        {
            title: "Something else",
            content: ['something', 'something else', 'other stuff', 'blah blah blah']            
        },      
    ],            
    sideContent:[ 
        {
            title: "About",
            content: ['something', 'something else', 'other stuff', 'blah blah blah']            
        }, 
        {
            title: "Something else",
            content: ['something', 'something else', 'other stuff', 'blah blah blah']            
        },      
    ],        
    pageTitle: "The main page title"

}]

Я пытаюсь создать форму, в которой человек может редактировать содержимое каждого элемента с помощью useReducer. Кажется, заголовок страницы отлично работает с моей формой и useReducer. Однако, когда я пытаюсь сопоставить основной контент, чтобы иметь возможность обновить любые его данные, я могу отобразить сопоставленные данные, но, похоже, не могу понять, как редактировать данные.

Форма для заголовка страницы

       <form className='form' onSubmit={onSubmit}>

            <input
                type='text'
                placeholder='pageTitle'
                value={state.pageTitle}
                onChange={(e) =>
                    dispatch({
                    type: 'page-title',
                    fieldName: 'pageTitle',
                    payload: e.currentTarget.value,
                    })
                }
            />
        </form>

Сопоставление основного содержимого для отображения

            {state.mainContent.map((event,index) => (
                
                <input
                    key={index}
                    type='text'
                    placeholder='main content'
                    value={event.title}
                    onChange={(e) =>
                        dispatch({
                        type: 'main-content',
                        fieldName: {} ,
                        payload: e.currentTarget.value,
                        })
                        
                    }
                    
                />
                
            ))}

Код редуктора...

function editReducer(state, action) {
    
    switch (action.type) {
        case 'page-title': {
            return {
                ...state,
                [action.fieldName]: action.payload,
            };
        }
        case 'main-content': {
            return {
                ...state,
                
                mainContent: [{
                    ...state.mainContent,
                    title: action.payload,   
                }]
            };
        }
        case 'OnSuccess':  
            return {  
                setLoading: false,
                
                pageTitle: action.payload.pageTitle, 
                mainContent: action.payload.mainContent,
                sideContent: action.payload.sideContent,

                error: ''  
            }  
        case 'OnFailure':  
            return {  
                loading: false,                  
                error: 'Something went wrong'  
            } 
      default:
        return state;
    }
}

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

Заранее благодарю за любую помощь.

Источник

Ответы (1)

avatar
GAntoine
1 июля 2021 в 18:54
0

В вашем исходном объекте mainContent — это массив, но в редьюсере вы обрабатываете его как объект.

mainContent: {
  ...state.mainContent,
  title: action.payload,   
}

Вы хотите выбрать конкретный объект в массиве mainContent. Либо назначьте каждому идентификатор и перестройте массив в редюсере, либо создайте дочерний компонент для каждого элемента и всплывайте с обновлением состояния.

JustinMcDonald
1 июля 2021 в 20:54
0

Спасибо, что предложили некоторое понимание. Я совершенно новый кодер (занимаюсь этим около 3 месяцев...) Я не совсем понимаю, как делать то, что вы предлагаете. Можете ли вы разбить это, пожалуйста, или если есть способ связаться с вами? был бы очень признателен за любой совет, который вы могли бы предложить.