我正在尝试将一些代码从类重构为功能组件,以便与我的应用程序的其他部分保持一致。这些类正在更新状态,在应用程序中,它们需要更新一个名为cardContext.js的上下文。我需要做的第一件事是将这些类重写到功能组件中,以便更新上下文而不是内部状态。
我的大部分网站都是通过带有钩子的功能组件工作的,我使用的是上下文。
每个上下文有3个文件;
- ExampleState.js
- exampleContext.js
- exampleReducer.js
到目前为止,应用程序的代码在这里https://codesandbox.io/s/infshot-978on?fontsize=14)(预览不起作用,因为我不认为codesandbox可以做全栈应用程序,但你可以通过客户端>src>components>card和客户端>srg>components>context>card查看相关代码。
我正在尝试将一些编码为类的组件集成到我的应用程序中,以同样的方式工作,这样我就可以集成它。首先,我需要重构这些组件,使它们成为功能组件,并以与应用程序其他部分相同的形式使用上下文。新组件使用了一个名为React Beautiful DND的框架,我使用创建类组件的教程创建了它们。
我一直在想如何重构它们。
我尝试重构的第一个文件在下面
// files in context/dnd editor are placeholders
import React from 'react';
import ReactDOM from 'react-dom';
import '@atlaskit/css-reset';
import 'materialize-css/dist/css/materialize.min.css';
import '../../index.css'
import styled from 'styled-components';
import { DragDropContext } from 'react-beautiful-dnd';
import initialData from './initialData';
import Column from './column';
const Container = styled.div`
display: flex;
`;
export default class dndEditor extends React.Component {
state = initialData;
onDragEnd = result => {
document.body.style.color = 'inherit';
const { destination, source, draggableId } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const start = this.state.columns[source.droppableId];
const finish = this.state.columns[destination.droppableId];
if (start === finish) {
const newTaskIds = Array.from(start.taskIds);
newTaskIds.splice(source.index, 1);
newTaskIds.splice(destination.index, 0, draggableId);
const newColumn = {
...start,
taskIds: newTaskIds
};
const newState = {
...this.state,
columns: {
...this.state.columns,
[newColumn.id]: newColumn
}
};
this.setState(newState);
return;
}
//Start and finnish columns are different
const startTaskIds = Array.from(start.taskIds);
startTaskIds.splice(source.index, 1);
const newStart = {
...start,
taskIds: startTaskIds
};
const finishTaskIds = Array.from(finish.taskIds);
finishTaskIds.splice(source.index, 0, draggableId);
const newFinish = {
...finish,
taskIds: finishTaskIds
};
const newState = {
...this.state,
columns: {
...this.state.columns,
[newStart.id]: newStart,
[newFinish.id]: newFinish
}
};
this.setState(newState);
return;
};
render() {
return (
<Container>
<DragDropContext onDragEnd={this.onDragEnd}>
{this.state.columnOrder.map(columnId => {
const column = this.state.columns[columnId];
const tasks = column.taskIds.map(
taskId => this.state.tasks[taskId]
);
return <Column key={column.id} column={column} tasks={tasks} />;
})}
</DragDropContext>
</Container>
);
}
}
这是initialData.js文件(初始状态(低于
const InitialData = {
tasks: {
'task-1': {
id: 'task-1',
content: 'Take out the trash and another thing also'
},
'task-2': { id: 'task-2', content: 'another link' },
'task-3': { id: 'task-3', content: 'clear desk' },
'task-4': { id: 'task-4', content: 'do pushups' }
},
columns: {
'column-1': {
id: 'column-1',
title: 'FACTS',
taskIds: ['task-2', 'task-3', 'task-4']
},
'column-2': {
id: 'column-2',
title: 'PROS',
taskIds: ['task-1']
},
'column-3': {
id: 'column-3',
title: 'CONS',
taskIds: []
}
},
columnOrder: ['column-1', 'column-2', 'column-3']
};
export default InitialData;
(我想重构的所有文件都在下面的函数代码沙盒中(https://codesandbox.io/s/react-beautiful-dnd-trello-example-ohxsi?fontsize=14
我不知道确切的挑战是什么。将setState
+this.state
重构为useState
应该是可行的。此组件提供上下文,而不是消耗上下文。因此,与上下文相关的一切都保持原样。
export default function DndEditor() {
const [state, setState] = useState(initialData);
onDragEnd = result => {
document.body.style.color = 'inherit';
const { destination, source, draggableId } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const start = state.columns[source.droppableId];
const finish = state.columns[destination.droppableId];
if (start === finish) {
const newTaskIds = Array.from(start.taskIds);
newTaskIds.splice(source.index, 1);
newTaskIds.splice(destination.index, 0, draggableId);
const newColumn = {
...start,
taskIds: newTaskIds
};
const newState = {
...this.state,
columns: {
...state.columns,
[newColumn.id]: newColumn
}
};
setState(newState);
return;
}
//Start and finnish columns are different
const startTaskIds = Array.from(start.taskIds);
startTaskIds.splice(source.index, 1);
const newStart = {
...start,
taskIds: startTaskIds
};
const finishTaskIds = Array.from(finish.taskIds);
finishTaskIds.splice(source.index, 0, draggableId);
const newFinish = {
...finish,
taskIds: finishTaskIds
};
const newState = {
...state,
columns: {
...state.columns,
[newStart.id]: newStart,
[newFinish.id]: newFinish
}
};
setState(newState);
return;
};
return (
<Container>
<DragDropContext onDragEnd={onDragEnd}>
{state.columnOrder.map(columnId => {
const column = state.columns[columnId];
const tasks = column.taskIds.map(
taskId => state.tasks[taskId]
);
return <Column key={column.id} column={column} tasks={tasks} />;
})}
</DragDropContext>
</Container>
);
}
此外,您可能希望将state
拆分为独立的
const [columns, setColumns] = useState(initialData.columns);
const [tasks, setTasks] = useState(initialData.tasks);
为了更好的可读性,但对于第一次尝试,[state, setState]
将是最简单的重构方法。