大家好,我是梅巴哥er
。前面写了关于redux的学习笔记。本篇介绍redux第三个小案例,每2秒自动点击按钮触发变色。这个案例有个需要特别注意的地方是,这是否需要用到异步action? 在什么情况下会用到异步action?
所谓异步,就是上一个事件和下一个事件不是同步进行的。
在该案例中,上一个事件是点击,下一个事件是触发变色。这两个事件是同步的,即点击后马上就会变色。只不过是每两次点击之间会间隔两秒时间。所以,这个案例仍然是同步action。
如果,案例是点击2秒后触发变色,那么点击时间和触发变色的时间就是先后进行,而非同步进行,这时候就是异步action了。
这个案例用了两种方法写的。方便大家更好的学习和加深认识。
老规矩,先看视图渲染效果:
Redux案例三
Redux红绿灯案例:每2秒自动点击按钮触发变色
PS:前面已经有过几个小案例了,这里就直接写代码,不重复赘述了。
1,用React编码
// 入口文件 index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App1 from './components/App1'
ReactDOM.render(
<App1 />,
document.getElementById('root')
)
// 组件 components/App1.js
import React, {
Component } from 'react'
export default class App1 extends Component {
constructor(props) {
super(props)
this.state = {
val: 1
}
}
componentDidMount() {
let val = this.state.val
this.timerID = setInterval(
() => this.handleClick(val),
2000
)
}
componentWillUnmount() {
clearInterval(this.timerID)
}
handleClick (val) {
this.setState({
val: this.state.val + 1
})
console.log('setval: ', this.state.val)
}
render() {
let val = this.state.val
console.log('val= ', val)
let isColor
if(val % 3 === 1) {
isColor = 'red'
} else if(val % 3 === 2) {
isColor = 'yellow'
} else if(val % 3 === 0) {
isColor = 'green'
}
return (
<div style={
{
width: 100, height: 100,textAlign: 'center'}}>
<div style={
{
backgroundColor: isColor, width: 100, height: 100, borderRadius: '50%'}}></div>
<button style={
{
marginTop: 5}}
onClick={
() => this.handleClick(val)} >
切换颜色
</button>
</div>
)
}
}
2,Redux编码:2秒后自动点击触发变色
- 注意,这个案例不是redux的异步action
- 因为这个是
2秒后自动点击触发变色
,是触发变色的同步action写在点击函数里,定时器里写点击函数 点击和变色是同步的
,所以不是异步action- 如果是
点击后2秒再触发变色
,就完全不一样了 - 这时的
点击和变色是不同步的
,也就是异步action - 写法就变成了 计时器写在点击函数里面,然后定时器写在异步action里,在定时器里分发同步action。
- 在react中的异步,是在
componentDidMount
中完成的
入口文件index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App2 from './containers/App2'
import {
Provider} from 'react-redux'
import store from './redux/store'
ReactDOM.render(
<Provider store={
store}>
<App2 />
</Provider>,
document.getElementById('root')
)
UI组件App1.js
import React, {
Component } from 'react'
import PropTypes from 'prop-types'
export default class App1 extends Component {
static propTypes = {
val: PropTypes.number.isRequired,
changeNumber: PropTypes.func.isRequired
}
componentDidMount() {
let {
val} = this.props
this.timerID = setInterval(
() => this.handleClick(val),
2000
)
}
componentWillUnmount() {
clearInterval(this.timerID)
}
handleClick = (val) => {
this.props.changeNumber(val)
}
render() {
let {
val} = this.props
let isColor
if(val % 3 === 1) {
isColor = 'red'
} else if(val % 3 === 2) {
isColor = 'yellow'
} else if(val % 3 === 0) {
isColor = 'green'
}
return (
<div style={
{
width: 100, height: 100,textAlign: 'center'}}>
<div style={
{
backgroundColor: isColor, width: 100, height: 100, borderRadius: '50%'}}></div>
<button style={
{
marginTop: 5}}
onClick={
() => this.handleClick(val)} >
切换颜色
</button>
</div>
)
}
}
容器组件App2.js
import {
connect} from 'react-redux'
import App1 from '../components/App1'
import {
changeNumber} from '../redux/actions'
export default connect(
state => ({
val: state}),
{
changeNumber}
)(App1)
action事件类型 action-types
// 事件类型
// 改变数字的action
export const CHANGENUMBER = 'changeNumber'
事件actions.js
// 事件actions
import {
CHANGENUMBER} from './action-types'
export const changeNumber = () => ({
type: CHANGENUMBER,
})
管理员reducers.js
// 管理员reducers
import {
CHANGENUMBER} from './action-types'
export function isChange(state = 1, action) {
switch(action.type) {
case CHANGENUMBER:
return state + 1
default:
return state
}
}
仓库store.js
import {
createStore} from 'redux'
import {
isChange} from './reducers'
const store = createStore(isChange)
export default store