redux-async评论管理

目录

1.工作流程

2.项目结构

3.源码效果

comment-add.jsx

comment-list.jsx

comment-item.jsx

app.jsx

index.js

actions.js

store.js

reducers.js


1.工作流程

redux最核心管理对象store

将actions中state,action与reducer联系在一起的对象

核心方法:getState()   /  dispatch(action);分发事件(发布)subscribe(listener) 订阅监听

redux​​​​​​​的connect()

2.项目结构

3.源码效果

comment-add.jsx

import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import {addComment} from '../../redux/actions'

class CommentAdd extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      username: '',
      content: ''
    }
    this.addComment = this.addComment.bind(this)
    this.changeUsername = this.changeUsername.bind(this)
    this.changeContent = this.changeContent.bind(this)
  }

  addComment () {
    // 根据输入的数据创建评论对象
    let { username, content } = this.state
    let comment = { username, content }
    // 添加到comments中, 更新state
    this.props.addComment(comment)
    // 清除输入的数据
    this.setState({
      username: '',
      content: ''
    })
  }

  changeUsername (event) {
    this.setState({
      username: event.target.value
    })
  }

  changeContent (event) {
    this.setState({
      content: event.target.value
    })
  }

  render () {
    return (
      <div className="col-md-4">
        <form className="form-horizontal">
          <div className="form-group">
            <label>用户名</label>
            <input type="text" className="form-control" placeholder="用户名"
                   value={this.state.username} onChange={this.changeUsername}/>
          </div>
          <div className="form-group">
            <label>评论内容</label>
            <textarea className="form-control" rows="6" placeholder="评论内容"
                      value={this.state.content} onChange={this.changeContent}></textarea>
          </div>
          <div className="form-group">
            <div className="col-sm-offset-2 col-sm-10">
              <button type="button" className="btn btn-default pull-right" onClick={this.addComment}>提交</button>
            </div>
          </div>
        </form>
      </div>
    )
  }
}
CommentAdd.propTypes = {
  addComment: PropTypes.func.isRequired
}

export default connect(
  null,
  {addComment}
)(CommentAdd)

comment-list.jsx

import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import CommentItem from '../comment-item/comment-item'
import './commentList.css'


class CommentList extends React.Component {

  render () {
    let comments = this.props.comments
    let display = comments.length > 0 ? 'none' : 'block'
    return (
      <div className="col-md-8">
        <h3 className="reply">评论回复:</h3>
        <h2 style={{ display: display }}>暂无评论,点击左侧添加评论!!!</h2>
        <ul className="list-group">
          {
            comments.map((comment, index) => {
              console.log(comment)
              return <CommentItem comment={comment} key={index} index={index}/>
            })
          }
        </ul>
      </div>
    )
  }
}
CommentList.propTypes = {
  comments: PropTypes.array.isRequired,
}

export default connect(
  state => ({comments: state.comments})
)(CommentList)

comment-item.jsx

import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'

import './commentItem.css'
import {deleteComment} from '../../redux/actions'

class CommentItem extends React.Component {
  constructor(props) {
    super(props)
  }

  deleteComment = () => {
    let username = this.props.comment.username
    if (window.confirm(`确定删除${username}的评论吗?`)) {
      this.props.deleteComment(this.props.index)
    }
  }

  render() {
    let comment = this.props.comment
    return (
      <li className="list-group-item">
        <div className="handle">
          <a href="javascript:" onClick={this.deleteComment}>删除</a>
        </div>
        <p className="user"><span>{comment.username}</span><span>说:</span></p>
        <p className="centence">{comment.content}</p>
      </li>
    )
  }
}

CommentItem.propTypes = {
  comment: PropTypes.object.isRequired,
  index: PropTypes.number.isRequired,
  deleteComment: PropTypes.func.isRequired
}

export default connect(
  null,
  {deleteComment}
)(CommentItem)

app.jsx

import React,{Component} from 'react'
import {connect} from 'react-redux'
import CommentAdd from '../../components/comment-add/comment-add'
import CommentList from '../../components/comment-list/comment-list'
import {addComment,deleteComment,getComments} from '../../redux/actions'

class App extends React.Component {

  componentDidMount() {
    //模拟异步获取数据
    this.props.getComments()
  }

  render() {
    return (
      <div>
        <header className="site-header jumbotron">
          <div className="container">
            <div className="row">
              <div className="col-xs-12">
                <h1>请发表对React的评论</h1>
              </div>
            </div>
          </div>
        </header>
        <div className="container">
          <CommentAdd/>
          <CommentList/>
        </div>
      </div>
    )
  }
}
//通过import {connect} from 'react-redux',把actions中的默认异步数据传给前端
export default connect(
  null,
  {getComments}
)(App)

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {Provider} from 'react-redux'
import store from './redux/store'
// 引入自定义模块必须使用相对路径
import App from './containers/app/app'
// 定义渲染根组件标签的函数
ReactDOM.render(
  (
    <Provider store={store}>
      <App/>
    </Provider>
  ),
  document.getElementById('root')
)

actions.js

/* 
包含了所有的action creator(action的工厂函数)
 */
import {
  ADD_COMMENT,
  DELETE_COMMENT,
  RECEIVE_COMMENTS
} from './action-types'
// 同步添加
export const addComment = (comment) => ({type: ADD_COMMENT, data: comment})
// 同步删除
export const deleteComment = (index) => ({type: DELETE_COMMENT, data: index})
// 同步接受comments
const receiveComments = (comments) => ({type: RECEIVE_COMMENTS, data: comments})
// 异步从后台获取数据
export const getComments = () => {
  return dispatch => {
	// 模拟发送ajax请求异步获取数据
    setTimeout(() => {
      const comments = [
        {
          username: "Tom",
          content: "ReactJS好难啊!",
          id: Date.now()
        },
        {
          username: "JACK",
          content: "ReactJS还不错!",
          id: Date.now() + 1
        }
      ]
	  // 分发一个同步的action
      dispatch(receiveComments(comments))
    }, 1000)
  }
}

store.js

/* 
redux最核心管理对象store:将actions中state,action与reducer联系在一起的对象
核心方法:
	getState()
	dispatch(action);分发事件(发布)
	subscribe(listener) 订阅监听
 */
import React from 'react'
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'

import reducers from './reducers'

// 根据counter函数创建store对象
export default createStore(
  reducers,
  composeWithDevTools(applyMiddleware(thunk)) // 应用上异步中间件
)

reducers.js
 

/* 
包含N个reducer函数(根据老的state和action返回一个新的state)
*/
import {combineReducers} from 'redux'

import {
  ADD_COMMENT,
  DELETE_COMMENT,
  RECEIVE_COMMENTS
} from './action-types'
//state要定义初始值
const initComments = []
//固定switch形式的流程处理
function comments(state = initComments, action) {
  switch (action.type) {
    case ADD_COMMENT:
	//根据actions.js可知action.data是个comment对象;...state在当前老数组前添加数据
      return [...state, action.data]
    case DELETE_COMMENT:
	//数组过滤不会改变原数组,会产生新数组
      return state.filter((c, index) => index !== action.data)
    case RECEIVE_COMMENTS:
      return action.data
    default:
      return state
  }
}
//暴露一个可以用export default,import reducers from './reducers'
//暴露多个不可以用export default,import {comments} from './reducers'
export default combineReducers({
  comments
})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值