У меня проблема с избыточной формой 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)));