中继本地状态管理。如何在客户端添加和使用标志?
Relay local state management. How to add and use flag on client side?
问题:
我想要一个简单的布尔标志,当模态打开时为 true
,关闭时为 false
。我想根据该标志更新其他组件
我希望有一种方法可以只使用中继 (Apollo has a solution for that)。我不想连接 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/>
);
} }
/>);
};
因为中继编译器向我抛出一个错误:GraphQLParser: Unknown field 'isModalOpened' on type 'Query'.
最后一个问题:
如何避免服务器请求?
该信息存储在客户端,因此无需请求。
我知道有一些类似的问题,例如 that and that。但是他们没有问 反应式更新 中最困难的部分,而且答案已经过时了。
如果你只需要存储一个标志,我建议你使用 React Context 而不是中继。你可以做下一步:
- 将上下文添加到 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>
)
}
}
- 随时随地从上下文中获取价值:
const MyComponent = (props) => {
const { isModalOpened } = useContext(ModalContext);
return (
<div>
{isModalOpened}
</div>
);
};
如果您将使用此解决方案,您将摆脱使用其他库,例如中继和服务器请求。
问题:
我想要一个简单的布尔标志,当模态打开时为 true
,关闭时为 false
。我想根据该标志更新其他组件
我希望有一种方法可以只使用中继 (Apollo has a solution for that)。我不想连接 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/>
);
} }
/>);
};
因为中继编译器向我抛出一个错误:GraphQLParser: Unknown field 'isModalOpened' on type 'Query'.
最后一个问题: 如何避免服务器请求? 该信息存储在客户端,因此无需请求。
我知道有一些类似的问题,例如 that and that。但是他们没有问 反应式更新 中最困难的部分,而且答案已经过时了。
如果你只需要存储一个标志,我建议你使用 React Context 而不是中继。你可以做下一步:
- 将上下文添加到 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>
)
}
}
- 随时随地从上下文中获取价值:
const MyComponent = (props) => {
const { isModalOpened } = useContext(ModalContext);
return (
<div>
{isModalOpened}
</div>
);
};
如果您将使用此解决方案,您将摆脱使用其他库,例如中继和服务器请求。