# redux_comments
**Repository Path**: duans/redux_comments
## Basic Information
- **Project Name**: redux_comments
- **Description**: 通过一个评论管理案例演示redux的使用
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2019-11-30
- **Last Updated**: 2022-06-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# redux使用介绍
## redux
### 核心方法
- createStore():创建store存储对象; 需要一个reducer函数作为参数
```js
import {createStore} from 'redux';
const store=createStore(reducer)
```
- getState(): 获取state状态数据
```js
store.getState()
```
- dispatch(): 触发action, 更新数据
```js
store.dispatch(action={type:'',data:''})
```
- subscribe(): 监听数据改变, 可以用来重新渲染页面
```js
store.subscribe(function(){
// 调用重新渲染组件的业务代码
})
```
- applyMiddleware(): 注册redux中间件
```js
import {createStore} from 'redux';
// 支持异步action的redux插件
import thunk from 'redux-thunk';
createStore(reducers,applyMiddleware(thunk))
```
- combineReducers(): 合并reducer函数
- redux/reducers.js
```js
import {combineReducers} from 'redux';
const comments=(state=[],action)=>{
switch(action.type){
case 'get_comments':
return action.data;
break;
case 'add_comments':
const arr = [...state];
const id=state.length>0?state[0].id+1:1;
arr.unshift({id,...action.data});
return arr;
break;
return
break;
case 'del_comments':
return state.filter((item) => item.id !== action.data);
break;
default:
return state;
}
}
export default combineReducers({
comments
})
```
## react-redux
- 链接react和redux的一个中间件
### 核心对象
- Provider: 容器组件
```js
```
- connect: 高阶组件; 链接react和redux, 将redux中维护的state状态和action方法传递给UI组件
```js
import App from '../Components/App'
connect({
(state)=>({comments:state.comments}),
{
get_comments,
add_comments,
del_commments,
get_comments_async
}
})(App)
```
## redux-thunk
- 支持异步action的redux插件
- redux/store.js
```js
import {applyMiddleware} from 'redux';
// 导入redux-thunk实现异步action
import thunk from 'redux-thunk';
const store=createStore(reducers,applyMiddleware(thunk));
```
- redux/actions.js
```js
// 同步action
export const get_comments=(data)>({type:'get_comments',data});
// 异步action,获取评论列表
export const get_comments_async=(data)=>{
return (dispatch)=>{
setTimeout(()=>{
// 该数据一般是通过ajax请求数据接口获取的
const data=[{
id: 1,
content: '我翻开这历史,这历史没有年代, 只是歪歪斜斜的每页都写着"仁义道德"四个字, 我横竖睡不着, 仔细看了半夜, 才从字缝中看出字来, 满本都写着两个字"吃人"',
user: '鲁迅'
}];
// 通过dispatch()触发同步action, 进而实现通过reducer更新state状态数据
dispatch(get_comments(data));
},2000);
}
}
```
## redux-devtools-extension
- redux调试工具; 需要配合谷歌插件`redux-devtools`
- redux/store.js
```js
// 导入reducers
import reducers from 'reducers';
// 导入调试工具所需的函数
import {composeWithDevTools} from 'redux-devtools-extension';
const store=createStore(reducers,composeWithDevTools())
```
# 评论管理案例
## redux/store.js
```js
// applyMiddleware()用来注册redux插件
import {createStore,applyMiddleware} from 'redux';
import reducers from './reducers';
// 导入redux-thunk实现异步action
import thunk from 'redux-thunk';
// 导入redux调试工具
import {composeWithDevTools} from 'redux-devtools-extension';
export const store=createStore(reducers,composeWithDevTools(applyMiddleware(thunk)));
```
## redux/reducers.js
```js
// 导入combineReducers()实现合并reducers
import { combineReducers } from 'redux';
import { GET_COMMENTS, ADD_COMMENTS, DEL_COMMENTS } from './action-types';
const initComments = []
const comments = (state = initComments, action) => {
switch (action.type) {
case GET_COMMENTS:
return action.data;
break;
case ADD_COMMENTS:
const arr = [...state];
const id=state.length>0?state[0].id+1:1;
arr.unshift({id,...action.data});
return arr;
break;
case DEL_COMMENTS:
return state.filter((item) => item.id !== action.data);
break;
default:
return state;
}
}
// 合并reducers并导出
export default combineReducers({comments})
```
## redux/actions.js
```js
import { GET_COMMENTS,ADD_COMMENTS,DEL_COMMENTS} from './action-types';
export const get_comments=(data)=>({type:GET_COMMENTS,data});
export const add_comments=(data)=>({type:ADD_COMMENTS,data});
export const del_comments=(data)=>({type:DEL_COMMENTS,data});
// 异步action,获取评论列表
export const get_comments_async=(data)=>{
return (dispatch)=>{
setTimeout(()=>{
// 该数据一般是通过ajax请求数据接口获取的
const data=[{
id: 1,
content: '我翻开这历史,这历史没有年代, 只是歪歪斜斜的每页都写着"仁义道德"四个字, 我横竖睡不着, 仔细看了半夜, 才从字缝中看出字来, 满本都写着两个字"吃人"',
user: '鲁迅'
}];
// 通过dispatch()触发同步action, 进而实现通过reducer更新state状态数据
dispatch(get_comments(data));
},2000);
}
}
```
## redux/action-types.js
```js
// action.type常亮定义
export const GET_COMMENTS='get_comments';
export const ADD_COMMENTS='add_comments';
export const DEL_COMMENTS='del_comments';
```
## containers/CommentsContainer.js
```js
// 导入connect高阶组件
import {connect} from 'react-redux';
// 导入UI组件
import Comments from '../components/Comments';
// 导入actions
import {get_comments,add_comments,del_comments,get_comments_async} from '../redux/actions';
export default connect(
(state)=>({comments:state.comments}),
{
get_comments,
add_comments,
del_comments,
get_comments_async
}
)(Comments)
```
## components/Comments.jsx
```jsx
import React from 'react';
// 导入子组件
import CmtAdd from './CmtAdd'
import CmtItem from './CmtItem';
import { thisExpression } from '@babel/types';
class Comments extends React.Component {
constructor(props) {
// 必须通过super调用父类的构造器方法
super(props);
}
componentWillMount(){
this.props.get_comments_async();
}
render() {
const comments=this.props.comments;
return (
评论管理
{comments.map((item, index) => (
))}
);
}
}
export default Comments;
```
## components/CmtAdd.jsx
```jsx
import React from 'react';
// 导入action
import * as actions from '../redux/actions';
export default class CmtAdd extends React.Component {
constructor(props) {
super(props);
this.state = {
user: '',
content: ''
}
}
// 实现user的双向数据绑定
userBind(e) {
const val = e.target.value;
this.setState({ user: val })
}
// 实现评论内容content的双向绑定
contentBind(e) {
const val = e.target.value;
this.setState({ content: val })
}
// 发布新评论
cmtAddHandle(){
if(this.state.user.trim()==''){
return alert('请输入姓名');
}
if(this.state.content.trim()==''){
return alert('请输入评论内容');
}
const data={
user:this.state.user,
content:this.state.content
}
this.setState({
user:'',
content:''
});
this.props.add_comments(data);
}
render() {
return (
)
}
}
```
## components/CmtItem.jsx
```jsx
import React from 'react';
// 导入actions
import * as actions from '../redux/actions';
export default class CmtItem extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
// 删除评论
delHandle(id){
this.props.del_comments(id);
}
render() {
return
评论内容: {this.props.content}
}
}
```
## index.js
```js
import React from 'react';
import ReactDOM from 'react-dom';
// 导入Provider组件
import { Provider } from 'react-redux';
// 导入store对象
import { store } from './redux/store';
// 此处直接打印store对象会报错
// console.log(store);
import './index.css';
// 导入评论组件Comments
import CommentsContainer from './containers/CommentsContainer';
ReactDOM.render(, document.getElementById('root'));
```