使用React-redux 进行应用数据的管理

本文介绍如何在React项目中引入Redux管理复杂状态,通过实例演示如何将组件的状态转移至Redux,并实现状态更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React 在处理小型的项目的时候是完全可以的。但是在处理复杂的项目时,React 自己是不够的。我们还需要使用redux 框架,帮助我们管理数据。

如果我们使用了redux 管理数据,那我们尽量把数据都放到redux 中进行管理。

下面,我们先把Header 组件中的focus 属性放到redux 中进行管理。

先下载安装 redux 与 react-redux

yarn add redux

yarn add react-redux

然后,我们在src 目录下新建一个目录 store。然后在store 下创建文件 index.js 在这儿新建store ,然后再新建一个文件 reducer.js 在这儿export 一个纯函数,作为 reducer。

先是 src/store/index.js 代码

import { createStore } from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;

然后是reducer.js 代码

const defaultState = {};

export default (state = defaultState, action) => {
    return state;
}

再,我们在App.js 中引入 store 和 react-redux,App.js 是整个项目整体解构的 js 文件。代码如下。

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { GlobalStyle } from './style.js';
import Header from './common/header';
import store from './store/index';

class App extends Component {
  render() {
    return (
      <div>
        <GlobalStyle />
        <Provider store={store}>
          <Header />
        </Provider>
      </div>
    );
  }
}

export default App;

然后,我们再去Header组件文件。src/common/header/index.js。在这个组件中,我们引入react-redux 的connect 。将这个组件与redux 中的store 做连接。

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {
  HeaderWrapper,
  Logo,
  Nav,
  NavItem,
  NavSearch,
  Addition,
  Button,
  SearchWrapper
} from './style';
import '../../statics/iconfont/iconfont.css';
import { CSSTransition } from 'react-transition-group';

class Header extends Component {
  constructor(props) {
    super(props);
    this.state = {
      focused: false
    }
    this.handleFocus = this.handleFocus.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
  }
  render () {
    return (
      <HeaderWrapper>
        <Logo href='/'/>
        <Nav>
          <NavItem className='left active'>首页</NavItem>
          <NavItem className='left'>下载</NavItem>
          <NavItem className='right'>登录</NavItem>
          <NavItem className='right'>
            <span className="iconfont">&#xe636;</span>
          </NavItem>
          <SearchWrapper>
            <CSSTransition
              in={this.state.focused}
              timeout={200}
              classNames="slide"
            >
              <NavSearch
                placeholder="搜索"
                className={this.state.focused ? "focused" : ""}
                onFocus={this.handleFocus}
                onBlur={this.handleBlur}
              ></NavSearch>
            </CSSTransition>
            <span
              className={this.state.focused ? "focused iconfont" : "iconfont"}
            >&#xe623;</span>
          </SearchWrapper>
        </Nav>
        <Addition>
        <Button className='writting'>
          <span className="iconfont">&#xe63a;</span>
          写文章
        </Button>
          <Button className='reg'>注册</Button>
        </Addition>
      </HeaderWrapper>
    )
  }

  handleFocus() {
    this.setState({
      focused: true
    })
  }

  handleBlur() {
    this.setState({
      focused: false
    })
  }

}

const mapStateToProps = (state) => {
  return {

  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

然后,我们把Header 组件中的focused 属性放到store 中。

先在src/store/reducer.js 中进行如下修改。

const defaultState = {
    focused: false
};

export default (state = defaultState, action) => {
    return state;
}

然后,我们改一下,获取focused 的方式 mapStateToProps 变量,如下。记得改一下focused 属性的使用方式 this.props.focused

const mapStateToProps = (state) => {
  return {
    focused: state.focused
  }
}

好的,接下来,我们来写一下修改focused 属性的方式 mapDispatchToProps 变量。同时记得改一下 输入框的 onFocus和 onBlur 事件的响应函数。如下。

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {
  HeaderWrapper,
  Logo,
  Nav,
  NavItem,
  NavSearch,
  Addition,
  Button,
  SearchWrapper
} from './style';
import '../../statics/iconfont/iconfont.css';
import { CSSTransition } from 'react-transition-group';

class Header extends Component {
  render () {
    const { focused, handleFocus, handleBlur } = this.props;
    return (
      <HeaderWrapper>
        <Logo href='/'/>
        <Nav>
          <NavItem className='left active'>首页</NavItem>
          <NavItem className='left'>下载</NavItem>
          <NavItem className='right'>登录</NavItem>
          <NavItem className='right'>
            <span className="iconfont">&#xe636;</span>
          </NavItem>
          <SearchWrapper>
            <CSSTransition
              in={focused}
              timeout={200}
              classNames="slide"
            >
              <NavSearch
                placeholder="搜索"
                className={focused ? "focused" : ""}
                onFocus={handleFocus}
                onBlur={handleBlur}
              ></NavSearch>
            </CSSTransition>
            <span
              className={focused ? "focused iconfont" : "iconfont"}
            >&#xe623;</span>
          </SearchWrapper>
        </Nav>
        <Addition>
        <Button className='writting'>
          <span className="iconfont">&#xe63a;</span>
          写文章
        </Button>
          <Button className='reg'>注册</Button>
        </Addition>
      </HeaderWrapper>
    )
  }

}

const mapStateToProps = (state) => {
  return {
    focused: state.focused
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    handleFocus () {
      const action = {
        type: "search_focus",
      };
      dispatch(action);
    },
    handleBlur () {
      const action = {
        type: "search_blur",
      };
      dispatch(action);
    }

  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

然后,我们再来改一下reducer.js 。如下。

const defaultState = {
    focused: false
};

export default (state = defaultState, action) => {
    if (action.type === "search_focus") {
        let newState = JSON.parse(JSON.stringify(state));
        newState.focused = true;
        return newState;
    }
    if (action.type === "search_blur") {
        let newState = JSON.parse(JSON.stringify(state));
        newState.focused = false;
        return newState;
    }
    return state;
}

好了。

这个时候,我们可以看到,Header 组件,变成了只有render 函数的组件,因此它可以被改写为无状态组件。如下。

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {
  HeaderWrapper,
  Logo,
  Nav,
  NavItem,
  NavSearch,
  Addition,
  Button,
  SearchWrapper
} from './style';
import '../../statics/iconfont/iconfont.css';
import { CSSTransition } from 'react-transition-group';

const Header = (props) => {
  return (
    <HeaderWrapper>
      <Logo href='/'/>
      <Nav>
        <NavItem className='left active'>首页</NavItem>
        <NavItem className='left'>下载</NavItem>
        <NavItem className='right'>登录</NavItem>
        <NavItem className='right'>
          <span className="iconfont">&#xe636;</span>
        </NavItem>
        <SearchWrapper>
          <CSSTransition
            in={props.focused}
            timeout={200}
            classNames="slide"
          >
            <NavSearch
              placeholder="搜索"
              className={props.focused ? "focused" : ""}
              onFocus={props.handleFocus}
              onBlur={props.handleBlur}
            ></NavSearch>
          </CSSTransition>
          <span
            className={props.focused ? "focused iconfont" : "iconfont"}
          >&#xe623;</span>
        </SearchWrapper>
      </Nav>
      <Addition>
      <Button className='writting'>
        <span className="iconfont">&#xe63a;</span>
        写文章
      </Button>
        <Button className='reg'>注册</Button>
      </Addition>
    </HeaderWrapper>
  )
}

const mapStateToProps = (state) => {
  return {
    focused: state.focused
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    handleFocus () {
      const action = {
        type: "search_focus",
      };
      dispatch(action);
    },
    handleBlur () {
      const action = {
        type: "search_blur",
      };
      dispatch(action);
    }

  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

Done.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值