以下操作建立安装好node在掌握了npm命令行本地配置完毕环境以后。
如果安装慢的话可以设置淘宝镜像源
类似vue-cli,官方提供了一个create-react-app脚手架,通过脚手架安装,无需配置webpack相关
-
全局安装create-react-app
npm install -g create-react-app
-
创建一个react项目
create-react-app react-demo
创建完毕以后的代码结构应该是这样的
让我们去掉一些src里面文件,让项目看起来干净一点。components,router,store分别为组件,路由和状态文件夹,底下会介绍。
-
component组件
在src目录下创建一个components文件夹
在components底下创建两个文件Home.jsx和Child.jsx
Home.jsx
import React, {Component} from 'react'; class Home extends Component { constructor(props){ super(props) } render(){ return ( <div class="home"> <h2>Home 页面</h2> </div> ) } } export default Home;
Child.jsx
function Topic({ match }) { return ( <div style={{color:'red'}}> <h3>{match.params.topicId}</h3> </div> ); } export default Topic;
这里的match是一个接收路由跳转路径参数的对象,它有一个属性params,里面的内容就是路径参数,除常用的params属性外,它还有url、path、isExact属性。
-
react路由
首先需要安装下路由,命令行执行
npm install react-router-dom --save
在src文件夹下创建一个router文件夹
在router文件夹下创建一个router.js文件
router.js
import React from 'react'; import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; import Home from '../components/Home'; import Child from '../components/Child'; function BasicRouter() { return ( <Router> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/childs">子路由组</Link> </li> </ul> <hr /> <Route exact path="/" component={Home} /> <Route path="/childs" component={ChildRouter} /> </div> </Router> ); } function ChildRouter({ match }) { return ( <div> <h2>子路由</h2> <ul> <li> <Link to={`${match.url}/child1`}>第一个子路由</Link> </li> <li> <Link to={`${match.url}/child2`}>第二个子路由</Link> </li> <li> <Link to={`${match.url}/child3`}>第三个子路由</Link> </li> </ul> <Route path={`${match.path}/:childId`} component={Child} /> <Route exact path={match.path} render={() => <h3>Please select a child.</h3>} /> </div> ); } export default BasicRouter;
然后改写下我们的App.js
import React from 'react'; import Router from './router/router'; class App extends React.Component { constructor(props){ super(props); } render() { return ( <div> <Router></Router> </div> ) } } export default App;
-
状态管理机
首先需要安装下redux(数据状态管理组件库),命令行执行
npm install redux --save
在src文件夹下创建store文件夹
在store文件夹下创建一个入口,一个动作类型,一个动作和一个状态机,一共4个文件
index.js
import {createStore} from 'redux'; import reducer from './reducer'; const store = createStore(reducer); export default store;
actionTypes.js
export const CHANGE_INPUT_TYPE ='change_input_type';
actionCreator.js
import { CHANGE_INPUT_TYPE } from './actionTypes'; export const getChangeItemAction = (value) => ({ type: CHANGE_INPUT_TYPE, value });
reducer.js
import { CHANGE_INPUT_TYPE } from './actionTypes'; const defaultState = { child1:'child1在store下的文本', child2:'child2在store下的文本', child3:'child3在store下的文本', } export default (state=defaultState, action)=>{ if(action.type === CHANGE_INPUT_TYPE){ // 深拷贝,reducer不允许直接修改state const newState = JSON.parse(JSON.stringify(state)); const value = action.value; newState[value.key] = value.value; return newState; } return state; }
store的简单配置完成,最后我们改写下Child.jsx,让它能够接收和修改store的state,就可以了
Child.jsx
import React from 'react'; import store from '../store'; import { getChangeItemAction } from '../store/actionCreator'; export default class Child extends React.Component { constructor(props){ super(props); this.state = store.getState(); store.subscribe(this.handleStoreChange); } render(){ const childText = store.getState()[this.props.match.params.childId]; return ( <div style={{color:'red'}}> <h3>{childText}</h3> <input onChange={this.inputChange}></input> </div> ) } inputChange = (e) =>{ const childId = this.props.match.params.childId; const action = getChangeItemAction({key:childId,value:e.target.value}); store.dispatch(action); } handleStoreChange = () => { this.setState(store.getState()); } }