首页 / 前端 / React.js / react使用react-redux
react使用react-redux
歪脖37684 React.js
885浏览
2022-04-23 23:05:49

1:安装

npm i redux
npm i react-redux

2:配置index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import TodoList from './todo_list/TodoList';
import store from './store';
import { Provider } from 'react-redux';

const App = () => (
  <Provider store={store}>
    <TodoList  />
  </Provider>
)

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
   // 严格模式:控制台会出现调用两次问题
   // 严格模式检查只在开发模式下运行,不会与生产模式冲突。
  // <React.StrictMode><TodoList /></React.StrictMode>
  <App  />
);

3:根目录新建store目录,创建index.js和reducer.js

index.js

import { createStore } from 'redux';
import reducer from './reducer'
const store = createStore(reducer);
export default store;

reducer.js

const defaultState = {
    inputVal: '',
    list: []
}
// reducer 可以接收state,但是绝对不能修改state
export default (state = defaultState, action) => {
    if(action.type === 'change_input_val'){
        let newState = JSON.parse(JSON.stringify(state));
        newState.inputVal = action.value;
        console.log(newState);
        return newState;
    }
    if(action.type === 'submit_input'){
        let newState = JSON.parse(JSON.stringify(state));
        newState.list.push(newState.inputVal)
        newState.inputVal = '';
        console.log(newState);
        return newState;
    }
    if(action.type === 'submit_delect_item'){
        let newState = JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index, 1);
        return newState;
    }
    return state;
}

组件中使用:

DEMO-todolist:

TodoList.js

import { Component, Fragment } from "react";
import TodoItem from "./TodoItem";
import './TodoList.css'
import { connect } from 'react-redux';

class TodoList extends Component{
  render() {
    return (
      <Fragment>
        <div className="input-box">
          <label htmlFor="inputId">输入框聚焦</label>
          <input 
            id="inputId"
            value={this.props.inputVal} 
            onChange={this.props.headleInputChange}/> 
          <button onClick={this.props.headleButtonClick}>提交</button>
        </div>
        <ul className="todo-ul">
          { this.getTodoItem() }
        </ul>
      </Fragment>
    )
  }
  // 获取数组dom
  getTodoItem(){
    return this.props.list.map((item, index) => {
      return (
        <TodoItem 
          key={index} 
          index={index} 
          content={item} 
          delItemClick={this.props.delItemClick} />
      )
    })
  }
}

const mapStateToProps = (state) =>{
  return {
      inputVal: state.inputVal,
      list: state.list
  }
}
const mapDispatchToProps = (dispatch) =>{
  return {
    // 输入框监听改变
    headleInputChange(e){
      const action = {
        type: 'change_input_val',
        value: e.target.value
      }
      dispatch(action)
    },
    // 点击提交按钮
    headleButtonClick(){
      const action = {
        type: 'submit_input'
      }
      dispatch(action);
    },
    // 删除列表项
    delItemClick(index){
      const action = {
        type: 'submit_delect_item',
        index: index
      }
      dispatch(action)
    }
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

TodoItem.js

import { Component } from "react";
import { PropTypes } from 'prop-types'

class TodoItem extends Component{
    constructor(props){
        super(props)
        this.sonItemClick = this.sonItemClick.bind(this);
    }
    render(){
        const { content } = this.props;
        return <li onClick={this.sonItemClick}>{content}</li>
    }
    sonItemClick(){
        let {delItemClick, index} = this.props;
        delItemClick(index)
    }
}
// 设置props传入的数据格式
TodoItem.propTypes = {
    content: PropTypes.string.isRequired,
    delItemClick: PropTypes.func,
    index: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}
//父组件未传参时设置默认值
TodoItem.defaultProps = {
    content: '默认值'
}
export default TodoItem;

TodoList.css

.input-box{
    display: flex;
    align-items: center;
}
.input-box label{
    cursor: pointer;
}
.input-box input,
.input-box button{
    box-sizing: border-box;
    border:  1px solid #ccc;
    height: 30px;
}
.input-box button{
    cursor: pointer;
}
.todo-ul li{
    cursor: pointer;
}


相关推荐