使用ReactJS使用Redux的简单状态更新事件

Simple state update event with Redux using ReactJS?

本文关键字:使用 更新 事件 状态 ReactJS Redux 简单      更新时间:2023-10-22

我已经学习了许多Redux和ReactJS教程。我理解设置actions=>action-creaters=>dispatch=>store=>render view(单向流)时使用更多数据实质性事件。我的问题是处理改变状态的非常简单的事件。我知道并非所有状态都需要在Redux中处理,并且本地状态事件(设置在React组件上)是一种可以接受的做法。然而,从技术上讲,Redux可以处理所有状态事件,这就是我正在尝试做的

这就是问题所在。我有一个React组件,它呈现一个按钮。此按钮有一个onClick事件,该事件会触发handleClick函数。我通过构造函数方法将Button的状态设置为isActive:false。当handleClick触发时,setState将设置为isActive:true。handleClick方法还运行两个if语句,当这两个语句的求值结果为true时,将运行一个函数来更改正文的背景色或段落文本的颜色。再次单击相同的按钮会将状态设置回false,并将正文颜色或文本颜色更改回原始值。此按钮组件在单独的组件Header中创建两次。长话短说,我有两个按钮。一个更改主体颜色,另一个更改单击事件后的p标记颜色。

这是按钮组件的代码:

import React, {Component} from 'react';
import {dimLights, invertColor} from '../../../actions/headerButtons';
import { connect } from 'react-redux';
import { Actions } from '../../../reducers/reducer';
const headerButtonWrapper = 'headerButton';
const headerButtonContext = 'hb--ctrls ';
const dimmedLight = '#333333';
const invertedTextColor = '#FFFFFF';
export default class Button extends Component {
  constructor (props) {
    super(props)
    this.state = {
      isActive: false
    };
  }
  handleClick (e) {
    e.preventDefault();
    let active = !this.state.isActive;
    this.setState({ isActive: active });
      if(this.props.label === "Dim The Lights"){
        dimLights('body', dimmedLight);
      }
      if(this.props.label === "Invert Text Color"){
        invertColor('p', invertedTextColor)
      }
  }
  render() {
    let hbClasses = headerButtonContext + this.state.isActive;
    return (
      <div className={headerButtonWrapper}>
        <button className={hbClasses} onClick={this.handleClick.bind(this)}>{this.props.label}</button>
      </div>
    );
  }
}

以下是处理颜色更改的导入函数的代码:

export function dimLights(elem, color) {
  let property = document.querySelector(elem);
    if (property.className !== 'lightsOn') {
        property.style.backgroundColor = color;
        property.className = 'lightsOn'
    }
    else {
        property.style.backgroundColor = '#FFFFFF';
        property.className = 'lightsOff';
    }
}
export function invertColor(elem, textColor) {
  let property = document.querySelectorAll(elem), i;
    for (i = 0; i < property.length; ++i) {
      if (property[i].className !== 'inverted') {
          property[i].style.color = textColor;
          property[i].className = 'inverted'
        } else {
          property[i].style.color = '#3B3B3B';
          property[i].className = 'notInverted';
      }
    }
}

这是减速器的代码:

import * as types from '../constants/ActionTypes';
const initialState = {
  isActive: false
};
export default function Actions(state = initialState, action) {
  switch (action.type) {
      case types.TOGGLE_LIGHTS:
      return [
        ...state,
        {
          isActive: true
        }
      ]
      default:
        return state
  }
}

以下是操作代码:

import EasyActions from 'redux-easy-actions';
export default EasyActions({
   TOGGLE_LIGHTS(type, isActive){
       return {type, isActive}
   }
})

如果有帮助的话,这里是呈现两个按钮组件的Header组件:

import React, {Component} from 'react';
import Button from './components/Button';
const dimmer = 'titleBar--button__dimmer';
const invert = 'titleBar--button__invert';
export default class Header extends Component {
  render() {
    return (
      <div id="titleBar">
        <div className="titleBar--contents">
          <div className="titleBar--title">Organizer</div>
            <Button className={dimmer} label="Dim The Lights" />
            <Button className={invert} label="Invert Text Color" />
        </div>
      </div>
    );
  }
}

最后,这是包含存储和到Redux的连接的代码(注意:Layout包含三个主要组件Header、Hero和Info。按钮仅在Header组件中创建)

import React, { Component } from 'react';
import { combineReducers } from 'redux';
import { createStore } from 'redux'
import { Provider } from 'react-redux';
import Layout from '../components/Layout';
import * as reducers from '../reducers/reducer';
const reducer = combineReducers(reducers);
const store = createStore(reducer);
// This is dispatch was just a test to try and figure this problem out
store.dispatch({
  type: 'TOGGLE_LIGHTS',
  isActive: true
})
console.log(store.getState())
export default class Organizer extends Component {
  render() {
    return (
        <Provider store={store}>
          <div>
            <Layout />
          </div>
        </Provider>
    );
  }
}

我想做的是将状态逻辑从本地React组件中删除并放入Redux。我觉得我导入的函数需要充当调度员。我也觉得我的初始动作设置不正确。这是一个非常简单的事件,很难在网上找到答案。有人想我能做些什么来解决这个问题吗?

您就快到了。看起来您遗漏了Layout组件的代码,我认为它就是呈现Button的组件。这里的关键部分将是您的容器,它是用Redux的connect包装的组件,用于将其链接到store。文档。更多详细信息请点击此处。

你做了什么:

// components/Button.js - pseudocode
import {dimLights, invertColor} from '../../../actions/headerButtons';
handleClick() {
  dimLights();
}

Redux希望您做什么:

// containers/App.js - pseudocode
import {dimLights, invertColor} from '../../../actions/headerButtons';
class App extends Component {
  render() {
    // Pass in your button state from the store, as well as 
    // your connected/dispatch-ified actions.
    return (
      <Button
        state={this.props.buttonState}
        onClick={this.props.buttonState ? dimLights : invertColor}
      />
    );
  }
}
function mapStateToProps(state, ownProps) {
  return {
    buttonState: state.buttonState
  };
}
export default connect(mapStateToProps, {
  // Your action functions passed in here get "dispatch-ified"
  // and will dispatch Redux actions instead of returning 
  // { type, payload }-style objects.
  dimLights, invertColor
})(App);

希望能有所帮助!Redux有很多像这样简单的东西的样板,但是,因为大多数部分都可以表示为纯函数,所以您可以获得很大的单元测试灵活性,并可以使用devtools调试器。