Прошлой ночью Инь Цинь шел дождь в третью ночь, и снова был холодный день. —— «Небеса куропатки» Су Ши
Результаты практики опубликованы на github по адресу:react-duce
Я не знаю, с каких пор управление состоянием стало стандартом фронтенд-проекта.Нужно нам это или нет, мы введем такие библиотеки, как MobX и Redux, для управления состоянием нашего приложения. Но если мы оглянемся назад на некоторые из архитектур в предыдущем проекте, мы не сможем не вздохнуть, почему дизайн связывает функции моего проекта так тесно, почему эта часть публичного состояния, которая не нуждается в извлекаться вообще, но почему извлекается состояние компонентов?В сочетании с пользовательским интерфейсом?
Студенты, которые использовали React с момента выпуска React, должны быть в состоянии вздохнуть, что каждый шаг в процессе разработки React шел стабильно, от миксина до компонента класса и функционального компонента; от чистого компонента до меморандумов — все они стремятся к лучшей производительности и лучшему Парадигма программы производительности. Если честно, с момента выхода хуков в react 16.8 мне больше понравился react, я еще подумал об управлении состоянием между компонентами, после чего сконденсировал эту библиотеку.react-duce
, надеюсь обсудить с вами практику хуков в проекте.
почему эта библиотека была разработана
Некоторое время назад я видел коммуникационную библиотеку swr, библиотеку запросов данных, основанную на хуках, принцип ее построения прост для понимания, когда возвращаемые данные запроса получены, вызывается функция обработки состояния для обновления состояния, а затем получается в компоненте, использующем состояние Data Update. Фрагмент исходного кода выглядит следующим образом:
import useSWR from 'swr'
function Profile () {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Хуки не только делают код более читабельным, но и уменьшают связь между модулями.
Ниже приведены некоторые примеры фрагментов кода:
import React from 'react';
import { createStore, useStore } from 'react-duce';
// 创建公共store
createStore('countStore', 0);
const HelloContent = () => {
// 使用公共store
const [ count, setCount ] = useStore('countStore');
return (
<span onClick={() => setCount(count + 1)}>{count}</span>
)
}
const WorldContent = () => {
// 使用公共store
const [ count ] = useStore('countStore');
return (
<span>{count}</span>
)
}
Нажмите span в компоненте HelloContent, чтобы вызвать обновление счетчика, а затем счетчик в WorldContent также обновится, реализуя совместное использование хранилища между компонентами.
Оставьте управление состоянием редюсеру
Когда-то мы сетовали на поток, сетовали на то, что избыточность делает наше управление состоянием более понятным и вселяет в нас уверенность в потоке данных.
Примеры использования следующие:
import React from 'react';
import { createStore, useStore } from 'react-duce';
// 定义reducer
const reducer = (state, action) => {
// you must return a new state value when a reducer is being used.
switch (action.type) {
case 'add':
const id = state.length;
return [
...state,
{ id, text: action.payload }
];
case 'delete':
return state.filter(todo => todo.id !== action.payload)
default:
return state;
}
}
// 创建指定reducer的store
const todoStore = createStore(
'todoStore',
[
{id: 0, text: 'Sing'}
],
reducer
);
function AddTodo() {
// 返回状态及dispatch函数
const [state, dispatch] = useStore('todoStore');
const inputRef = React.useRef(null);
const onSubmit = e => {
e.preventDefault();
const todo = inputRef.current.value;
inputRef.current.value = '';
// 触发状态更新
dispatch({ type: 'add', payload: todo });
};
return (
<form onSubmit={onSubmit}>
<input ref={inputRef} />
<button>Create</button>
</form>
);
}
function TodoList() {
const [todos, dispatch] = useStore(todoStore);
const deleteTodo = id => dispatch({ type: 'delete', payload: id });
return (
<ul>
<h2>todolist</h2>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
<button onClick={() => deleteTodo(todo.id)} type="button">
X
</button>
</li>
))}
</ul>
);
}
export { TodoList, AddTodo };
Принцип реализации
Магазин базового класса
class Store {
name;
state;
reducer;
dispatchers;
dispatch;
subscribe(callback) {};
dispatch(action, callback) {};
}
создать магазин
export function createStore(name, state = {}, reducer) {
const store = new Store(name, state, reducer);
?stores = Object.assign({}, ?stores, {[name]: store})
}
использовать магазин
export function useStore(identifier) {
const store = getStoreItem(identifier);
// 使用useState创建状态与处理函数
const [state, set] = useState(store.state);
useEffect(() => {
// ...
}, [])
return [state, store.dispatch];
}
Когда функция состояния выполняется, состояние обновляется и просматриваются все установленные функции состояния.