最近本人一直在研究redux在项目中开发,在实际项目中开发中离不开的是form表单,在react开发中有redux-form提供了这个组件进行form表单的开发
一、本案例是在之前案例的基础上移入了redux-form
如果不有不清楚之前案例的请查看React-Redux链接React与Redux开发项目
二、目录结构
|react-redux-demo
|----webpack.config.js
|----package.json
|----index.html //引入了bootstrap.css
|----node_modules //存放工具包
|----src
|--------index.js //入口文件
|--------actions
|------------index.js
|--------components
|------------ShowData.js
|------------SimpleForm.js //新增
|--------containers
|------------ShowDataConnect.js
|--------reducers
|------------getJson.js
|------------index.js
|--------utils
|------------fetch.js //修改了用promise
三、各文件代码
- 3.1
webpack.config.js
文件代码:
/**
* @author:水痕
* @time:2017-02-25 17:27
* @email:332904234@qq.com
* @version:1.0
* @fileName:webpack.config
* @title:
*/
'use strict';
module.exports = {
entry:{
index:'./src/index.js',
},
output:{
path:__dirname,
filename:'[name].build.js',
},
module:{
loaders:[
{
test:/\.(js|jsx)$/,
exclude:'/node_modules/',
loader:'babel-loader',
query:{
presets:['es2015','react']
}
}
]
},
resolve:{
extensions:['.js',".css",".jsx"]
}
}
- 3.2
package.json
代码如下:
{
"name": "react-demo05",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --inline --host localhost --port 3000"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.23.1",
"babel-loader": "^6.3.2",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.23.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-redux": "^5.0.3",
"redux": "^3.6.0",
"redux-form": "^6.6.1",
"redux-thunk": "^2.2.0",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1"
}
}
- 3.3
index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
</body>
<script src="./index.build.js"></script>
</html>
- 3.4
src/index.js
代码
/**
* @author:水痕
* @time:2017-04-06 10:23
* @email:332904234@qq.com
* @version:1.0
* @fileName:index
* @direction:
* @title:
*/
'use strict';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {createStore, applyMiddleware} from 'redux';
import {Provider} from 'react-redux';
import thunk from 'redux-thunk';
import counter from './reducers';
//引入容器组件
import ShowDataConnect from './containers/ShowDataConnect';
const store = createStore(counter, applyMiddleware(thunk));
const rootEl = document.getElementById('root');
ReactDOM.render(
<Provider store={store}>
<div>
<ShowDataConnect />
</div>
</Provider>, rootEl);
- 3.5
src/utils/fetch.js
代码:
/**
* @author:水痕
* @time:2017-04-06 09:05
* @email:332904234@qq.com
* @version:1.0
* @fileName:fetch
* @direction:
* @title:封装一个fetch请求方法
*/
'use strict';
export function getJSON(url) {
return new Promise((fulfilled, reject) => {
fetch(url).then((response) => response.json())
.then((data) => fulfilled(data))
.catch(error => reject(error));
})
}
- 3.6
src/action/index.js
代码:
/**
* @author:水痕
* @time:2017-04-06 09:26
* @email:332904234@qq.com
* @version:1.0
* @fileName:index
* @direction:
* @title:创建一个actions
*/
'use strict';
//引入请求数据的方法
import {getJSON} from './../utils/fetch';
//定义一个常量
export const ASYNCGETDATA = "ASYNCGETDATA";
export function getData() {
return (dispatch,getState)=>{
getJSON('http://www.xxxx.com/xxx.php?c=Product&a=category').then((data)=>{
dispatch({type: ASYNCGETDATA, dataSet: data})
})
}
}
- 3.7
src/componens/ShowData.js
代码
/**
* @author:水痕
* @time:2017-04-06 09:15
* @email:332904234@qq.com
* @version:1.0
* @fileName:ShowData
* @direction:
* @title:定义一个展现数据的视图组件
*/
'use strict';
import React, {Component} from "react";
import SimpleForm from './SimpleForm';
export default class ShowData extends Component {
render() {
let {getData, data:{data}} = this.props;
return (
<div className='container'>
<div className='row'>
<div className='col-md-6'>
<h3 className='text-center text-primary'>使用react-redux和fetch请求数据</h3>
<div style={{margin: '30px auto'}}>
<input type="button" value="点击展示数据" onClick={() => getData()} className='btn btn-danger'
style={{cursor: 'pointer'}}/>
</div>
<ul className="list-group">
{
data ? data.map((item, index) => (
<li key={`list-${index}`} data-id={`list-${item.id}`}
className="list-group-item">{item.name}</li>
)) : null
}
</ul>
</div>
<div className='col-md-6'>
<SimpleForm/>
</div>
</div>
</div>
)
}
}
ShowData.propTypes = {
getData: React.PropTypes.func.isRequired
}
- 3.8
src/components/SimpleForm.js
代码:
/**
* @author:水痕
* @time:2017-04-01 15:27
* @email:332904234@qq.com
* @version:1.0
* @fileName:form
* @direction:
* @title:
*/
'use strict';
import React from 'react'
import {Field, reduxForm} from 'redux-form';
const SimpleForm = (props) => {
const {handleSubmit, pristine, reset, submitting} = props
console.log(props);
return (
<div>
<form onSubmit={handleSubmit(values => console.log(values))} role="form">
<div className="form-group">
<label>用户名:</label>
<div>
<Field name="name" component="input" type="text" placeholder="请输入用户名" className="form-control"/>
</div>
</div>
<div className="form-group">
<label>密码:</label>
<div>
<Field name="password" component="input" type="password" placeholder="请输入密码" className="form-control"/>
</div>
</div>
<div className="form-group">
<button type="submit" className="btn btn-sm btn-success" disabled={pristine || submitting} style={{marginRight:"20px"}}>提交</button>
<button type="button" className="btn btn-sm btn-primary" disabled={pristine || submitting} onClick={reset}>清除</button>
</div>
</form>
</div>
)
}
export default reduxForm({
form: 'simple'
})(SimpleForm)
- 3.9
src/containers/ShowDataConnect.js
代码:
/**
* @author:水痕
* @time:2017-04-06 09:32
* @email:332904234@qq.com
* @version:1.0
* @fileName:ShowDataConnect
* @direction:
* @title:
*/
'use strict';
import ShowData from './../components/ShowData';
import {connect} from 'react-redux';
import * as ActionCreators from '../actions';
export default connect(function (state) {
console.log('容器组件',state);
return{
data: state.getJson,
}
},ActionCreators)(ShowData)
- 3.10
src/reducers/getJson.js
代码:
/**
* @author:水痕
* @time:2017-04-06 09:36
* @email:332904234@qq.com
* @version:1.0
* @fileName:getJson
* @direction:
* @title:
*/
'use strict';
import {ASYNCGETDATA} from './../actions';
export default function getJson(state={},action) {
switch (action.type){
case ASYNCGETDATA:
return Object.assign({},state,action.dataSet);
default:
return state;
}
}
- 3.11
src/reducers/index.js
代码:
/**
* @author:水痕
* @time:2017-04-06 09:37
* @email:332904234@qq.com
* @version:1.0
* @fileName:index
* @direction:
* @title:
*/
'use strict';
import {combineReducers} from 'redux';
import {reducer as formReducer} from 'redux-form';
import getJson from './getJson';
const rootReducer = combineReducers({
getJson,
form: formReducer
});
export default rootReducer;