【问题标题】:Gatsby-Redux: Component doesn't re-render on state changesGatsby-Redux:组件不会在状态更改时重新渲染
【发布时间】:2019-10-27 10:17:16
【问题描述】:

当我在我的 Gatsby 项目中实现 Redux 时,我看到当组件的状态发生变化时我的组件不会重新渲染(是的,我将状态视为不可变的)。

所以我使用了 Redux 的 Conuter example,并将其代码复制到我的 Gatsby 项目中。 并且问题再次发生,当状态更改时组件无法重新渲染(使用 Redux 的示例之一!)。

只有使用this.forceUpdate(),我才能让组件在状态更改时重新渲染,当我删除此行时,它停止在状态更改时重新渲染。

这是我创建的 Gatsby 页面和我复制到的 Redux 代码:

import React, { Component } from 'react'
import { createStore } from 'redux'

class Counter extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    console.log("render - start",JSON.stringify(store.getState(),null,2))
    const { value, onIncrement, onDecrement } = this.props
    return (
      <p>
        Clicked: {value} times
        {' '}
        <button onClick={onIncrement}>
          +
        </button>
        {' '}
        <button onClick={onDecrement}>
          -
        </button>
      </p>
    )
  }
}

const counter = (state = 0, action) => {
  console.log("reducer - start: ",state, JSON.stringify(action,null,2))
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

const store = createStore(counter)

class TestPage extends React.Component {
  render(){
    return (
      <Counter
        value={store.getState()}
        onIncrement={() => {
          store.dispatch({ type: 'INCREMENT' })
          // this.forceUpdate()
        }}
        onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
      />)
  }
}

export default TestPage

【问题讨论】:

  • 我也试过 store.subscribe(),但结果更奇怪(只调用了 TestPage 的 render 方法,而不是它的子 Counter 组件的 render 方法)。 constructor(p) { super(p) this.counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default:返回状态 } } this.store = createStore(this.counter) this.store.subscribe(this.render.bind(this)) }
  • 我已验证调用了 TestPage 的渲染方法,而不是其子 Counter 组件的渲染方法 - 通过将 console.log() 调用作为它们的第一行插入。在页面加载时 - 两者都被调用,但是如上所述,当状态改变时,只有父级报告记录......

标签: javascript reactjs redux state gatsby


【解决方案1】:

你是否正确地 store.subsribe() ?

我让它像这样工作。

index.js

import React, { Component } from "react";
import ReactDOM from "react-dom";
import { store } from "./store";
import Counter from "./Counter";

class App extends Component {
  render() {
    return (
      <Counter
        value={store.getState()}
        onIncrement={() => {
          store.dispatch({ type: "INCREMENT" });
        }}
        onDecrement={() => store.dispatch({ type: "DECREMENT" })}
      />
    );
  }
}

const rootElement = document.getElementById("root");
const render = () => ReactDOM.render(<App />, rootElement);

render();
store.subscribe(render);

store.js

import { createStore } from "redux";

const counter = (state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
};


export const   store = createStore(counter);

Counter.js

import React, { Component } from 'react'

class Counter extends Component {

  render() {

    const { value, onIncrement, onDecrement } = this.props
    return (
      <p>
        Value: {value} 
        {' '}
        <button onClick={onIncrement}>
          +
        </button>
        {' '}
        <button onClick={onDecrement}>
          -
        </button>
      </p>
    )
  }
}

export default Counter;

示例代码框: https://codesandbox.io/s/redux-counter-2oftu

顺便说一句在 react 中使用 redux 没有多大意义,我们一般使用 react-redux 包。在学习了 redux 基础知识之后,你绝对应该使用 react-redux 包。

https://react-redux.js.org/

【讨论】:

  • 在问题的评论中,您可以看到我使用 store.subsribe() 的不成功尝试。但是,您的最后一段回答了我的问题,因为我不知道 React-Redux 甚至存在。当然,它解决了这个问题等等......
猜你喜欢
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多