Redux-форма Firebase - Оригинальные поля push - PullRequest
0 голосов
/ 08 апреля 2020

У меня проблема с избыточной формой FieldArray. В функции AddExercise у меня есть props.items, и у всех элементов есть больше полей в бэкэнде Firebase, но когда я пытаюсь вставить их sh в бэкэнд с новыми полями, он не может этого сделать.

Если я использую вот так

<FieldArray name={`exercises.${index}.${{uid: item.id}}.exerciseSets`} component={renderSets} />

всегда включаю [Object object] ошибка в ответе JSON.

У вас есть идеи, как можно sh элементы в бэкэнд со всеми исходными полями с новыми добавленными полями (renderSets)?

const AddExercise = (
    props
) => {
    return (
        <Segment>
            <Droppable droppableId='ADDED_EXERCISES'>
                {(provided, snapshot) => (
                    <ul ref={provided.innerRef} className='shopping-bag'>
                        {props.items.map((item, index) => (
                            <Draggable key={item.id} draggableId={item.id} index={index}>
                                {(provided, snapshot) => (
                                    <li
                                        ref={provided.innerRef}
                                        {...provided.draggableProps}
                                        {...provided.dragHandleProps}
                                        style={provided.draggableProps.style}
                                    >
                                        <Segment>
                                            <p textalign="left">{item.exerciseNumber} - {item.exerciseName}</p>
                                            <br />
                                            <FieldArray name={`exercises.${index}.${{uid: item.id}}.exerciseSets`} component={renderSets} />
                                        </Segment>
                                    </li>
                                )}
                            </Draggable>
                        ))}
                        {provided.placeholder}
                    </ul>
                )}
            </Droppable>
        </Segment>
    );
};

import React, { useState, useCallback, useEffect, useRef } from 'react';
import firebase from '../../../firebase/firebase';
import { v4 as uuid } from 'uuid';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { Field, FieldArray } from 'redux-form';
import { Grid, Button, Segment } from 'semantic-ui-react';
import { connect } from 'react-redux';
import './styles.css';
import { withFirestore } from 'react-redux-firebase';
import { withRouter } from 'react-router-dom';
import nextId from 'react-id-generator'

const id = nextId('');

const mapStateToProps = (state, ownProps) => ({
    workoutId: ownProps.match.params.id,
    workouts: state.workout
})

const renderField = ({
    input,
    label,
    type,
    meta: {
        touched,
        error
    }
}) => {
    return (
        <div>
            <label>{label}</label>
            <div>
                <input {...input} type={type} placeholder={label} />
                {touched && error && <span>{error}</span>}
            </div>
        </div>
    )
};

const renderSets = ({
    fields,
    meta: {
        error
    }
}) => {
    return (
        <Grid columns={2}>
            <Grid.Row>
                <Grid.Column textAlign="left" width="4">
                    <Button type='button' onClick={() => fields.push()}>Add Set</Button><br />
                </Grid.Column>
                <Grid.Column width="16">
                    {fields.map((set, index) => (
                        <li key={index}>
                            <Grid columns={5} textAlign='center'>
                                <Grid.Row>
                                    <Grid.Column verticalAlign='middle' width="1">
                                        <p>{index + 1}</p>
                                    </Grid.Column>
                                    <Grid.Column>
                                        <Field
                                            name={`${set}.weight`}
                                            type='text'
                                            component={renderField}
                                            label='kg/ibs'
                                        />
                                    </Grid.Column>
                                    <Grid.Column>
                                        <Field
                                            name={`${set}.reps`}
                                            type='text'
                                            component={renderField}
                                            label='rN.'
                                        />
                                    </Grid.Column>
                                    <Grid.Column>
                                        <Field
                                            name={`${set}.restTime`}
                                            type='text'
                                            component={renderField}
                                            label='rT.'
                                        />
                                    </Grid.Column>
                                    <Grid.Column verticalAlign='bottom' width="1">
                                        <Button type='button' onClick={() => fields.remove(index)}>X</Button>
                                    </Grid.Column>
                                </Grid.Row>
                            </Grid>
                        </li>
                    ))}
                    {error && <li className='error'>{error}</li>}
                </Grid.Column>
            </Grid.Row>
        </Grid>
    )
};

function MoveExercise(props) {
    return (
        <Segment>
            <Droppable droppableId={props.droppableId} isDropDisabled={true}>
                {(provided, snapshot) => (
                    <ul ref={provided.innerRef} className={props.className}>
                        {props.items.map((item, index) => (
                            <Draggable key={item.id} draggableId={item.id} index={index}>
                                {(provided, snapshot) => (
                                    <Segment>
                                        <li
                                            ref={provided.innerRef}
                                            {...provided.draggableProps}
                                            {...provided.dragHandleProps}
                                            style={provided.draggableProps.style}
                                            className={snapshot.isDragging ? 'dragging' : ''}
                                        >
                                            {item.exerciseNumber} - {item.exerciseName}
                                        </li>
                                        {snapshot.isDragging && (
                                            <li className='react-beatiful-dnd-copy'>{item.exerciseNumber} - {item.exerciseName}</li>
                                        )}
                                    </Segment>
                                )}
                            </Draggable>
                        ))}
                        {provided.placeholder}
                    </ul>
                )}
            </Droppable>
        </Segment>
    );
};

function Exercises(props) {
    return <MoveExercise droppableId='DRAG' className='shop' items={props.items} />;
};

const AddExercise = (
    props
) => {
    return (
        <Segment>
            <Droppable droppableId='ADDED_EXERCISES'>
                {(provided, snapshot) => (
                    <ul ref={provided.innerRef} className='shopping-bag'>
                        {props.items.map((item, index) => (
                            <Draggable key={item.id} draggableId={item.id} index={index}>
                                {(provided, snapshot) => (
                                    <li
                                        ref={provided.innerRef}
                                        {...provided.draggableProps}
                                        {...provided.dragHandleProps}
                                        style={provided.draggableProps.style}
                                    >
                                        <Segment>
                                            <p textalign="left">{item.exerciseNumber} - {item.exerciseName}</p>
                                            <br />
                                            <FieldArray name={`exercises.${index}.${{uid: item.id}}.exerciseSets`} component={renderSets} />
                                        </Segment>
                                    </li>
                                )}
                            </Draggable>
                        ))}
                        {provided.placeholder}
                    </ul>
                )}
            </Droppable>
        </Segment>
    );
};

const reorder = (list, startIndex, endIndex) => {
    const [removed] = list.splice(startIndex, 1);
    list.splice(endIndex, 0, removed);
    return list;
};

const copy = (source, destination, droppableSource, droppableDestination) => {
    console.log(destination)
    console.log(source)
    const item = source[droppableSource.index];
    console.log(item)
    destination.splice(droppableDestination.index, 0, { ...item, id: uuid() });
    return destination;
};

function DndInput(props) {
    const [loadedExercises, setLoadedExercises] = useState([]);
    const loadedExercisesRef = useRef([]);
    console.log(loadedExercisesRef)
    console.log(loadedExercises);
    const [addedExercises, setAddedExercises] = useState([]);
    const addedExercisesRef = useRef([])
    console.log(addedExercises);

    useEffect(() => {
        firebase
            .firestore()
            .collection('exercises')
            .where('ownerUid', '==', 'platform')
            .onSnapshot((snapshot) => {
                const newExercises = snapshot.docs.map((doc) => ({
                    id: doc.id,
                    ...doc.data()
                }));
                loadedExercisesRef.current = newExercises;

                setLoadedExercises(newExercises);
            });
        // const id = props.workouts.map(workout => workout.id)
        // const uid = props.workoutId

        //   if (uid) {
        //     firebase
        //       .firestore()
        //       .collection('workouts')
        //       .where('uid', '==', uid)
        //       .onSnapshot((snapshot) => { 
        //         const existsExercises = snapshot.docs.map((doc) => ({
        //           exercises: doc.exercises
        //         }));
        //     addedExercisesRef.current = existsExercises;
        //     setAddedExercises(existsExercises);
        //   });
        // }
    }, []);


    const onDragEnd = useCallback(
        result => {
            const { source, destination } = result;
            console.log(result);
            console.log(source);
            console.log(destination);

            if (!destination) {
                return;
            }

            switch (source.droppableId) {
                case destination.droppableId:
                    setAddedExercises(state =>
                        reorder(state, source.index, destination.index)
                    );
                    break;
                case 'DRAG':
                    setAddedExercises(state =>
                        copy(loadedExercisesRef.current, state, source, destination)
                    );
                    break;
                default:
                    break;
            }
        },
        [setAddedExercises]
    );
    return (
        <div className='App'>
            <DragDropContext onDragEnd={onDragEnd}>
                <Grid columns={2}>
                    <Grid.Row>
                        <Grid.Column>
                            <h2>Exercises</h2>
                            <Exercises items={loadedExercisesRef.current} />
                        </Grid.Column>
                        <Grid.Column>
                            <h2>Added Exercises</h2>
                            <AddExercise items={addedExercises} />
                        </Grid.Column>
                    </Grid.Row>
                </Grid>
            </DragDropContext>
        </div>
    );
}

export default withFirestore(withRouter(connect(mapStateToProps, undefined)(DndInput)));

...