大家好,我是梅巴哥er
。本篇介绍redux应用的第二个小案例。对于同一个项目,分别用react和redux进行编写,方便我们更好的理解。
Redux案例二
点击按钮切换背景颜色案例
老规矩,先来看下案例渲染效果图:
1,创建项目create-react-app redux_demo2
2,删除src
文件夹里的文件
3,在src
文件夹里创建index.js
文件
4,在src
文件夹里创建components
文件夹,负责放UI组件
5,在components
文件夹创建App.js
UI组件
6,打开控制台,npm start
,查看是否正常渲染。如果渲染正常,说明创建项目正确。
7,先来看下用React
的做法:
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
ReactDOM.render(
<App />,
document.getElementById('root')
)
// src/components/App.js
// 点击按钮,切换图案背景颜色
import React, {
Component } from 'react'
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isColor: true
}
}
handleClick = (isColor) => {
this.setState({
isColor: !isColor
})
}
render() {
const isColor = this.state.isColor
return (
<div>
<div style={
{
backgroundColor: isColor ? 'red' : 'pink', width: '100px', height: '100px'}} ></div>
<button onClick={
() => this.handleClick(isColor)} >
// 注意这里
// 如果Click没有参数,就可以直接写onClick={this.handleClick}
// 如果Click有参数,{}里就要用箭头函数了
// onClick={() => this.handleClick(isColor)}
// 不然会报错 isColor is undefined
// 原因是React不会自动绑定this,不绑定this的情况下,
// this.handleClick这个函数是指向window的,
// 函数就会去window里找参数。肯定找不到。
// 所以需要用箭头函数来绑定this
// 这里还有一种不用箭头函数的写法
// onClick={this.handleClick.bind(this, isColor)
{
isColor ? 'Red' : 'Pink'}
</button>
</div>
)
}
}
8,再来看下Redux
的做法:
8.1 安装redux
,prop-types
和react-redux
npm install redux --save
npm install react-redux --save
npm install prop-types --save
8.2 动手之前先想一下思路
-
这里有个
button
的点击事件,所以我们需要一个action
-
能让状态发生变化的是
reducer
,所以我们还需要一个reducer
-
有状态的参与,
store
肯定是不能少的 -
现在来考虑状态的变化
- 首先有个初始状态
state
,定义state=true
- 然后得到一个经过reducer处理的新状态
newState
- 再需要一个变量
isColor
来接收这个状态值
- 首先有个初始状态
-
有了状态,需要根据状态变化,来改变渲染的结果
-
因为这里的渲染结果是两个,要么是
red
,要么是pink
。所以可以用三元运算符判断 -
关于定义的变量
isColor
- 首先,定义变量的类型,需要用到
prop-types
- 其次,把state的值给到变量,并且把action和UI组件连接起来,需要用到
{connect}
- 把state的值给到变量之后,我们怎么在UI组件里拿到
isColor
的值呢?const {isColor} = this.props
- 首先,定义变量的类型,需要用到
-
一切都准备好了,开始渲染。我们需要一个接收
store
的第三方组件,把要渲染的组件包裹起来。需要用到<Provider store={store}>xx</Provider>
8.3 准备就绪,开始动手写代码。
- 入口文件
index.js
import React from 'react' // 凡是要写jsx语法代码的地方,这句引入都必须有
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组件
components/App.js
// 点击按钮,切换图案背景颜色
import React, {
Component } from 'react'
import PropTypes from 'prop-types'
export default class App extends Component {
static propTypes = {
isColor: PropTypes.bool.isRequired,
changeColor: PropTypes.func.isRequired
}
handleClick = () => {
this.props.changeColor()
}
render() {
const {
isColor} = this.props
return (
<div>
<div style={
{
backgroundColor: isColor ? 'red' : 'pink', width: '100px', height: '100px'}} ></div>
<button onClick={
this.handleClick} >
{
isColor ? 'Red' : 'Pink'}
</button>
</div>
)
}
}
- 容器组件
containers/App2.js
import {
changeColor} from '../redux/actions'
import {
connect} from 'react-redux'
import App from '../components/App'
export default connect(
state => ({
isColor: state}),
{
changeColor}
)(App)
- 事件名称
redux/action-types
// 点击变色的action类型
export const CHANGECOLOR = 'changeColor'
- 事件
redux/actions
// 点击变色的action
import {
CHANGECOLOR} from './action-types'
export const changeColor = () => ({
type: CHANGECOLOR,
})
- 仓库管理员
redux/reducers
import {
CHANGECOLOR} from './action-types'
export function isChange(state=true, action) {
switch(action.type) {
case CHANGECOLOR:
return !state
default:
return state
}
}
- 仓库
redux/store
import {
createStore} from 'redux'
import {
isChange} from './reducers'
const store = createStore(isChange)
export default store
后话:
- 可以看到的是,当我们处理一个简单的项目时,react要简单的多,而redux就要复杂了很多
- 但是也可以看到,redux的条理是非常清晰的,编码套路也很有特点
- redux入门概念多,入门有点难度,但是正因为理解之后的清晰思路,redux在大型项目中就更有优势了。
-----------------------------完毕。