react使用react-redux
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;
}
好文推荐