首页 > 解决方案 > 中继本地状态管理。如何在客户端添加和使用标志?

问题描述

问题:

我想要一个简单的布尔标志,true当模式打开和false关闭时。我想被动地更新其他组件取决于该标志

我希望有一种方法可以只使用中继(阿波罗有一个解决方案)。我不想连接 mobx 的 redux 或类似的东西(这只是简单的布尔标志!)。

我已经拥有的:

可以使用它commitLocalUpdate来修改您的状态。事实上,我能够像这样创建和修改我的新标志:

class ModalComponent extends PureComponent {
    componentDidMount() {
        // Here I either create or update value if it exists
        commitLocalUpdate(environment, (store) => {  
            if (!store.get('isModalOpened')) {
                store.create('isModalOpened', 'Boolean').setValue(true);
            } else {
                store.get('isModalOpened').setValue(true);
            }
        });
    }

    componentWillUnmount() {
        // Here I mark flag as false
        commitLocalUpdate(environment, (store) => {
            store.get('isModalOpened').setValue(false);
        });
    }

    render() {
        // This is just react component so you have full picture
        return ReactDOM.createPortal(
            <div
                className={ styles.modalContainer }
            >
                dummy modal
            </div>,
            document.getElementById('modal'),
        );
    }
}

挑战:

如何响应性地更新其他组件取决于该标志? 我无法像这样获取我的标志:


const MyComponent = (props) => {
    return (
    <QueryRenderer
        environment={ environment }
        query={ graphql`
            query MyComponentQuery {
                isModalOpened
            }`
        } //PROBLEM IS HERE GraphQLParser: Unknown field `isModalOpened` on type `Query`
        render={ ({ error, props: data, retry }) => {

            return (
                <div>
                    {data.isModalOpened}
                <div/>
            );
        } }
    />);
};

因为 Relay 编译器给我一个错误:GraphQLParser: Unknown field 'isModalOpened' on type 'Query'.

最后一个问题: 如何避免服务器请求? 该信息存储在客户端,因此无需请求。

我知道有一些类似问题。但是他们没有询问反应更新中最困难的部分,而且答案已经过时了。

标签: reactjsgraphqlrelayjsrelay

解决方案


如果您只需要存储一个标志,我建议您使用React Context而不是 Relay。你可以做下一步:

  1. 将上下文添加到 App 组件:
const ModalContext = React.createContext('modal');

export class App extends React.Component {
    constructor() {
        super();
        this.state = {
            isModalOpened: false
        }
    }

    toggleModal = (value) => {
        this.setState({
            isModalOpened: value
        })
    };

    getModalContextValue() {
        return {
            isModalOpened: this.state.isModalOpened,
            toggleModal: this.toggleModal
        }
    }

    render() {
        return (
            <ModalContext.Provider value={this.getModalContextValue()}>
                //your child components
            </ModalContext.Provider>
        )
    }

}

  1. 从任何你想要的上下文中获取价值:
const MyComponent = (props) => {
    const { isModalOpened } = useContext(ModalContext);

    return (
        <div>
            {isModalOpened}
        </div>
    );
};

如果您将使用此解决方案,您将摆脱使用其他库,例如中继和服务器请求。


推荐阅读