Централизованное управление состоянием без Redux или Mobx?

#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 делают под капотом.