Reactjs 为cookie管理创建单独的react组件

Reactjs 为cookie管理创建单独的react组件,reactjs,cookies,react-cookie,Reactjs,Cookies,React Cookie,我有一个组件,如果它的prop.paramA与存储在cookie中的paramA值不同,它就会进行渲染 下面是我将cookie管理逻辑移动到单独组件中的尝试。问题是,当showQuestion为false时,问题组件只呈现一次,因此我永远看不到问题 目前,我的代码如下所示 // question.js import React from 'react'; import ToggleDisplay from 'react-toggle-display'; import {withCookies,

我有一个组件,如果它的prop.paramA与存储在cookie中的paramA值不同,它就会进行渲染

下面是我将cookie管理逻辑移动到单独组件中的尝试。问题是,当showQuestion为false时,问题组件只呈现一次,因此我永远看不到问题

目前,我的代码如下所示

// question.js
import React from 'react';
import ToggleDisplay from 'react-toggle-display';
import {withCookies, Cookies} from 'react-cookie';

class Question extends React.Component {

    static get propTypes() {
        return {
            cookies: instanceOf(Cookies).isRequired
        }
    }

    constructor(props) {
        super(props);
        this.state = {
            paramA: props.paramA,
            showQuestion: props.showQuestion
        };
    }

    componentDidMount() {
        if (this.state.showQuestion) {
            // do some ajax calls etc.
        }
    }

    render() {
        return (
            <div id="simplequestion">
                <ToggleDisplay show={this.state.showQuestion}>
                    <div>What is your SO profile?</div>
                </ToggleDisplay>
            </div>
        );
    }
}

export default withCookies(Question);
//question.js
从“React”导入React;
从“反应切换显示”导入切换显示;
从“react cookie”导入{withCookies,Cookies};
类问题扩展了React.Component{
静态get propTypes(){
返回{
cookies:instanceOf(cookies)。需要
}
}
建造师(道具){
超级(道具);
此.state={
帕拉玛:道具,帕拉玛,
showQuestion:props.showQuestion
};
}
componentDidMount(){
if(this.state.showQuestion){
//做一些ajax调用等。
}
}
render(){
返回(
你的个人资料是什么?
);
}
}
导出带有cookies的默认值(问题);
我编写了以下CookieManager组件-

// cookiemanager.js
import React from 'react';
import {withCookies, Cookies} from 'react-cookie';

class CookieManager extends React.Component {
    static get propTypes() {
        return {
            cookies: instanceOf(Cookies).isRequired
        }
    }

    constructor(props) {
        super(props);
        let propA = props.cookies.get('propA');
        if (!propA || propA !== props.propA) {
            props.cookies.set('propA', props.propA, { path: '/', maxAge: 604800});
            console.log('changed', propA, props.propA);
            props.propAChanged(true);
        } else if (propA === props.propA) {
            console.log('unchanged', propA, props.propA);
            props.propAChanged(false);
        }
    }
    render() { 
        return <div id="cookieManager"></div>;
    }
}
export default withCookies(CookieManager);
//cookiemanager.js
从“React”导入React;
从“react cookie”导入{withCookies,Cookies};
类CookieManager扩展了React.Component{
静态get propTypes(){
返回{
cookies:instanceOf(cookies)。需要
}
}
建造师(道具){
超级(道具);
让propA=props.cookies.get('propA');
如果(!propA | | propA!==props.propA){
set('propA',props.propA,{path:'/',maxAge:604800});
console.log('changed',propA,props.propA);
props.propa已更改(true);
}否则如果(propA==props.propA){
console.log('unchanged',propA,props.propA);
道具。更改道具(错误);
}
}
render(){
返回;
}
}
导出带有cookies的默认值(CookieManager);
以下是顶级应用程序

// app.js
import React from 'react';
import Question from './question';
import CookieManager from './cookiemanager';
import { CookiesProvider } from 'react-cookie';


class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            paramA: props.paramA,
            showQuestion: false,
            avoidUpdate: false
        };
        this.updateShowQuestion = this.updateShowQuestion.bind(this);
    }

    updateShowQuestion(x) {
        if (this.state.avoidUpdate) {
            return;
        }
        this.setState({
            paramA: this.state.paramA,
            showQuestion: x,
            avoidUpdate: !this.state.avoidUpdate
        });
    }

    componentWillUpdate(nextProps, nextState) {
        if (!nextState.avoidUpdate && nextState.paramA === this.state.paramA) {
            this.setState({
                paramA: this.state.paramA,
                showQuestion: this.state.showQuestion,
                avoidUpdate: true
            });
        }
    }

    render() {
        return (
            <CookiesProvider>
                <CookieManager paramA={this.state.paramA} ridChanged={this.updateShowQuestion}>
                <Question
                    paramA={this.state.paramA}
                    showQuestion={this.state.showQuestion}/>
                </CookieManager>
            </CookiesProvider>
        );
    }
}
export default App;
//app.js
从“React”导入React;
从“./问题”导入问题;
从“/CookieManager”导入CookieManager;
从“react cookie”导入{CookiesProvider};
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
帕拉玛:道具,帕拉玛,
问题:错,
避免更新:false
};
this.updateShowQuestion=this.updateShowQuestion.bind(this);
}
更新show问题(x){
if(this.state.avoidUpdate){
返回;
}
这是我的国家({
帕拉玛:这个州,帕拉玛,
问题:x,,
avoidUpdate:!this.state.avoidUpdate
});
}
组件将更新(下一步,下一步状态){
如果(!nextState.avoidUpdate&&nextState.paramA===this.state.paramA){
这是我的国家({
帕拉玛:这个州,帕拉玛,
showQuestion:this.state.showQuestion,
避免更新:正确
});
}
}
render(){
返回(
);
}
}
导出默认应用程序;

您正在从这里的州政府阅读:


但是
showQuestion
仅在构造函数中设置一次:

this.state={
帕拉玛:道具,帕拉玛,
showQuestion:props.showQuestion
};
this.props
更改时,将呈现组件,但您仍在读取未更新的
this.state
,因此可见输出是相同的

我认为有两种方法可以解决这个问题:

  • 每当道具更改时,更新
    this.state.showQuestion

    静态getDerivedStateFromProps(下一步,上一步){
    if(nextrops.showQuestion!==prevState.showQuestion)
    返回{showQuestion};
    }
    
  • render()
    中,阅读
    this.props.showQuestion

    
    
    这种方法看起来更容易,但使用另一种方法,您可以获得对状态更改的更细粒度控制


您还遗漏了另一件事:

组件将更新(下一步,下一步状态){
如果(!nextState.avoidUpdate&&nextState.paramA===this.state.paramA){
这是我的国家({
帕拉玛:这个州,帕拉玛,
showQuestion:this.state.showQuestion,//此行
避免更新:正确
});
}
}
您正在接收新道具,但您正在设置旧状态:
showQuestion:this.state.showQuestion
。相反,从新道具-
nextrops
设置新的
showQuestion
值,方法如下:

组件将更新(下一步,下一步状态){
如果(!nextState.avoidUpdate&&nextState.paramA===this.state.paramA){
这是我的国家({
帕拉玛:这个州,帕拉玛,
showQuestion:nextrops.showQuestion,//此行
避免更新:正确
});
}
}

换句话说:当Cookie更改时,您希望再次呈现您的
CookieManager
吗?我希望在CookieManager更改时再次呈现问题showQuestionBtw,无需在
componentWillUpdate()
paramA:this.state.paramA,
中写入
setState()
。您可以省略它-旧状态保持原样,只有新传递的对象被分配到
状态
。呈现条件是:如果参数与其在cookie中的值相比发生变化,则显示问题,否则不显示问题。我设法让cookiemanager只渲染了一次,但当showQuestion更改时,应用程序的渲染方法仍然没有被再次调用。您的建议在问题中很有用,但在决定渲染的父组件中却没有Question@comiventor我发现你错在哪里了。编辑