#reactjs #redux #state #mobx #state-management
#reactjs #redux #состояние #mobx #управление состоянием
Вопрос:
Недавно я обдумал идею централизованного управления состоянием в своих приложениях React без использования Redux или Mobx, вместо этого решив создать что-то похожее на класс application в Android. В любом случае, я реализовал нечто подобное этому:
Создайте папку хранилища и файл с именем store.js в нем содержимое которого:
// State
let state = {
users: {},
value: 0
};
// Stores references to component functions
let triggers = [];
// Subscription Methods
export const subscribe = trigger => {
triggers.push(trigger);
trigger();
}
export const unsubscribe = trigger => {
let pos = -1;
for (let i in triggers) {
if (triggers[i]===trigger) {
pos = i;
break;
}
}
if (pos!==-1) {
triggers.splice(pos, 1);
}
}
// Trigger Methods
let triggerAll = () => {
for (let trigger of triggers) {
trigger();
}
}
// State Interaction Methods
export const setUser = (name, description) => {
state.users[name] = description;
triggerAll();
}
export const removeUser = name => {
if (name in state.users) {
delete state.users[name];
}
triggerAll();
}
export const getAllUsers = () => {
return state.users;
}
export const getUser = name => {
if (!(name in state.users)) {
return null;
}
return state.users[name];
}
export const getValue = () => {
return state.value;
}
export const setValue = value => {
state.value = value;
triggerAll();
}
И подключение к этому хранилищу следующим образом:
// External Modules
import React, { Component } from 'react';
import {Box, Text, Heading} from 'grommet';
// Store
import {subscribe, unsubscribe, getAllUsers} from '../../store/store';
class Users extends Component {
state = {
users: []
}
componentDidMount() {
subscribe(this.trigger); // push the trigger when the component mounts
}
componentWillUnmount() {
unsubscribe(this.trigger); // remove the trigger when the component is about to unmount
}
// function that gets triggered whenever state in store.js changes
trigger = () => {
let Users = getAllUsers();
let users = [];
for (let user in Users) {
users.push({
name: user,
description: Users[user]
});
}
this.setState({users});
}
render() {
return <Box align="center">
{this.state.users.map(user => {
return <Box
style={{cursor: "pointer"}}
width="500px"
background={{color: "#EBE7F3"}}
key={user.name}
round
pad="medium"
margin="medium"
onClick={() => this.props.history.push("/users/" user.name)}>
<Heading margin={{top: "xsmall", left: "xsmall", right: "xsmall", bottom: "xsmall"}}>{user.name}</Heading>
<Text>{user.description}</Text>
</Box>
})}
</Box>;
}
}
export default Users;
Примечание. Я протестировал этот шаблон на веб-сайте, и он работает. Проверьте это здесь. И я прошу прощения, я пытаюсь сделать вопрос кратким для stackoverflow, я предоставил более подробное объяснение реализации шаблона здесь
Но в любом случае, мой главный вопрос, каковы могут быть возможные причины не использовать это, поскольку я предполагаю, что если бы это было так просто, люди не использовали бы Redux или Mobx. Заранее спасибо.
Ответ №1:
Это то, что в основном делают Redux и MobX, вы ошибаетесь, думая, что по своей основной концепции они сильно отличаются. Их размер и сложность стали результатом их усилий по нейтрализации ошибок и адаптации к огромному разнообразию случаев применения. Вот и все. Хотя они могут подходить к задаче с разных точек зрения, но основная концепция именно в этом. Возможно, вам следует ознакомиться с тем, что они на самом деле делают под ним.
Кстати, вам не нужно сохранять избыточное состояние в вашем компоненте, если все, что вам нужно, это запустить обновление. Вы можете просто вызвать forceUpdate() напрямую:
// function that gets triggered whenever state in store.js changes
trigger = () => {
this.forceUpdate();
}
Это похоже на то, что привязки Redux и MobX для react делают под капотом.