新建review.php,测试用的后端php代码,我们使用了redis来代替数据库操作
<?php
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET,POST');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
$redis = new Redis();
$redis->connect("127.0.0.1", 6379);
$result = '';
function sendReview($content) {
global $redis;
$redis->lpush("newsreview", $content);
return $redis->lrange("newsreview", 0, 10);
}
if (isset($_GET["review"]) && trim($_GET["review"]) != "") {
$result = sendReview($_GET["review"]);
} else {
$result = $redis->lrange("newsreview", 0, 10);
}
exit(json_encode($result));
main.js
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore,applyMiddleware } from 'redux'
import { Provider,connect} from 'react-redux'
import createSaga from 'redux-saga'
import { ReviewReduce } from './redux/ReviewReduce'
import { Review_saga_load, Review_saga_post } from './redux/ReviewSaga'
let saga = createSaga()
let store = createStore(ReviewReduce, applyMiddleware(saga))
saga.run(Review_saga_load)
saga.run(Review_saga_post)
function mapStateToProps (state) {
return {
reviewList: state.rlist
}
}
function mapDispatchToProps (dispatch) {
return {
loadReview: () => dispatch({ type: 'REVIEW_LOAD' }),
postReview: v => dispatch({ type: 'REVIEW_POST', content: v })
}
}
class TestReviewList extends React.Component {
componentWillMount () {
const { loadReview } = this.props
loadReview()
}
render () {
const { reviewList, postReview } = this.props
return <div>
<div className = 'newscontent'>
<h1>全球的开发新趋势调查</h1>
<article>在全球著名 IT 技术网站 Stack Overflow 上,我们可以基于该网站的开发者调查数据,了解全球的开发新趋势及动态。 Stack Overflow 分析了其网站上各编程语言的标签的访问情况: 发达国家程序员喜欢 Python、R(重视科研)、C 与 C++(重视教育); 欠发达国家的喜欢 PHP 与 Android 开发 </article>
</div>
<h2>评论区域</h2>
<dl>
<dt>输入评论内容</dt>
<dd><textarea className='review' ref = { e => this.textarea = e } /></dd>
<dd><input className = 'cmd' type = 'button' value = '提交' onClick = { () => postReview(this.textarea.value) }/></dd>
</dl>
<h3>评论列表区域</h3>
<ul>
{
reviewList.map((item, index) => {
return <li key = { index }> { item } </li>
}
)}
</ul>
</div>
}
}
const App = connect(mapStateToProps, mapDispatchToProps)(TestReviewList)
ReactDOM.render(
<Provider store = { store }>
<App/>
</Provider>,
document.getElementById('root')
)
redux/ReviewReduce.js
export const ReviewReduce = function (state = { content: '', rlist: [] }, action) {
switch (action.type) {
// 评论框内容改变
case 'REVIEW_CONTENT_CHANGE':
return Object.assign({}, state, { content: action.content })
// 加载或重新加载评论成功
case 'REVIEW_LOAD_SUCCESS':
return Object.assign({}, state, { rlist: action.reviewdata })
default:
return state
}
}
redux/ReviewSaga.js
import { call, put, takeEvery, select, take, fork, cancel, cancelled } from 'redux-saga/effects'
import axios from 'axios'
import qs from 'qs'
class ReviewAPI {
//第一次加载评论
static loadReview () {
return axios.get('http://localhost:8080/review.php').then(res => res.data)
}
//发送评论
static postReview (content) {
return axios.get('http://localhost:8080/review.php?review=' + content).then(res => res.data)
}
}
export const Review_saga_load = function* () {
// 定义【加载评论】任务
const action = yield take('REVIEW_LOAD')
// ajax:得到评论的数据
const result = yield call(ReviewAPI.loadReview)
// dispatch:加载或重新加载评论成功
yield put({ type: 'REVIEW_LOAD_SUCCESS', reviewdata: result })
}
export const Review_saga_post = function* () {
while (true) {
// 定义【提交评论】任务,这里的action 包含传递进来的参数
const action= yield take('REVIEW_POST')
// ajax:提交评论
yield call(function* () {
// 获取所有的state
const state = yield select()
const result = yield call(ReviewAPI.postReview, action.content)
yield put({ type: 'REVIEW_LOAD_SUCCESS', reviewdata: result })
})
}
}
知识点总结:
1、如何给元素绑定onClick事件时传参?毕竟传参的话会执行该函数。
答案:箭头函数
onClick = { () => postReview(this.textarea.value) }
2、dispatch调用saga的时候如何接收参数?
答案:分为takeEvery 和 take两种
// 如果是takeEvery的话,就是这样
yield takeEvery("SAGA_002", function* (action) {
console.log(action)
})
// 如果是take的话,就是这样
const action= yield take('REVIEW_POST')
console.log(action)