1.脚手架css
npm install -g create-react-app
使用方法:create-react-app XXX(项目名称),会自动init并install好项目,直接npm start就行了。
html
react-scripts
是create-react-app
生成项目全部的依赖。
一般状况下,咱们建立spa
应用时是使用npm
安装项目依赖,在经过配置webpack.config.js
进行配置,搭建好环境后在src
编写源代码。而create-react-app
是自动构建,在package.json
中只有react-scripts
做为依赖,而在reacr-scripts
中已经配置好了项目全部须要的。另外,关于webpack.config.js,须要使用eject命令导出。react
引用:http://www.javashuo.com/article/p-dzabjhck-gp.htmlwebpack
EnterData(event){ const {textBox} = this.state; if(event.keyCode==13){ this.setState( {textBox:textBox.concat(event.target.value)} ); } }
3.setState与Statesweb
this.state={ textBox:[] }
this.setState( {textBox:textBox.concat(event.target.value)} );
可是使用的时候,依然须要:npm
const {textBox} = this.state;
先取下来再进行数据操做。json
4.CSS元素使用redux
let diagramContainer={ padding: '20px', width: window.innerWidth, height: window.innerHeight, border: '1px solid gray' };
<div className="Dotcon" style={diagramContainer}>
<div id={pid} style={{position:'absolute',height:'80px',width:'80px',border:'1px solid blue',color:'blue',float:'left',left:pleft,top:ptop}}>{pid}</div>
var name1 ="Mike"; var age1=20; var message1=`hello,${name1},your age is ${age1}`;
6.JS数组CRUDbash
追加:
textBox.concat(event.target.value)
删除:
var index; const {textBox} = this.state; for(var i=0;i<textBox.length;i++){ if(textBox[i]==value){ index = i; break; } } textBox.splice(index,1);
7.弹框操做(person就是输入的值)
var person=prompt("请输入你的名字","Harry Potter");
8.父子组件传值与回调
首先要将接收方法在父组件传入子组件,子组件的click(或其余事件)事件里再次调用父组件的方法(这个方法已经传入,因此能够从props里拿到,从而回调)。
onChildDelete(value) { //这里拿到的value靠子组件传回 }
return ( <div className="InputComponent"> <AddText onChildDelete={this.onChildDelete.bind(this)} /> </div> ); //注意这里必须.bind(this),不然在onChildDelete方法不可用this.props
onChildDelete(){ this.props.onChildDelete(this.props.Text) } render() { return ( <div className="AddText"> <li>{this.props.Text}<a onClick={this.onChildDelete.bind(this)}></a></li> </div> ); //子组件调用父组件传进来的方法,进行回调,并传回一个值。
引用:http://www.javashuo.com/article/p-efacyojj-co.html
9.数组Map与事件响应
const BlackComponent = () => <div>我是黑色组件</div>;
class App extends React.Component { constructor(props) { super(props); this.state = { comps: [] }; } render() { const { comps } = this.state; return ( <div> {comps.map(comp => { return <BlackComponent key={comp} />; })} <p>---------------</p> <button onClick={() => this.setState({ comps: comps.concat([Date.now()]) })}>加组件</button> </div> ); } }
//固然,map还能够传入index值
10.取Input的值
import React , {Component} from 'react'; export default class App extends Component{ search(){ const inpVal = this.input.value; console.log(inpVal); } render(){ return( <div> <input type="text" ref={input => this.input = input} defaultValue="Hello"/> <button onClick={this.search.bind(this)}></button> </div> ) } }
https://blog.csdn.net/Shuiercc/article/details/81383679
10.安装淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
11.react-router的使用
import {BrowserRouter,Route,Switch} from 'react-router-dom' <BrowserRouter> <Switch> <Route exact path='/' render={() => <FirstPage/>} /> <Route path='/RabbitMessageQueue' component={InputComponent}/> <Route path='/TodoList' component={TodoList}/> </Switch> </BrowserRouter> //须要先注册路由,带exact默认为第一个页面且必须。 在其余组件中: import {Link} from 'react-router-dom';
<ul> <li style={{color:color}}><Link style={{color:color}} to='/'>Home</Link></li> <li style={{color:color}}><Link style={{color:color}} to='/RabbitMessageQueue'>RabbitMessageQueue</Link></li> <li style={{color:color}}><Link style={{color:color}} to='/TodoList'>TodoList</Link></li> </ul>
12.redux的使用
在主页面中,注册store,并配置到全局。
import { createStore} from 'redux' import { Provider } from 'react-redux' const store = createStore(dataHandler); function createStore { switch (action.type) { case 'CHANGE_THEME': return { themeColor: action.color }; default: return state; } } render() { return ( <Provider store={store}> <BrowserRouter> ... </BrowserRouter> </Provider> ); } //须要把最外层组件囊括进provider,这样数据才能在全部组件可用。
在子组件中(MenuList):
import { connect } from 'react-redux'; function mapStateToProps(state) { return { themeColor: state.themeColor } } function mapDispatchToProps(dispatch) { return { setThemeColor: (type,value) => dispatch({ type: type, color: value }), } } export default connect( mapStateToProps, mapDispatchToProps )(MenuList) //mapStateToProps让redux的state同步到react的props中,而mapDispatchToProps同理,将dispatch方法同步到了props中。
而后,你就能够在组件中使用:
const { setThemeColor} = this.props; const color = this.props.themeColor; <button onClick={()=>{setThemeColor('CHANGE_THEME','#3399FF')}}>Normal</button> <li style={{color:color}}><Link style={{color:color}} to='/'>Home</Link></li>
在另外的组件中共享数据也须要这么作。
function mapStateToProps(state) { return { themeColor: state.themeColor } } export default connect(mapStateToProps)(Header) //而后你就能够同步全部组件中的themeColor的变化了,而props数据的改变一样会让render从新绘制。
能够看到,使用redux能够作到跨组件数据同步,而不须要将数据先一步步传递给父组件,再传递给另外一个子组件。若是加上@解释器,会更加优雅。
class AutoFocusTextInput extends React.Component { componentDidMount() { this.textInput.focusTextInput(); } render() { return ( <CustomTextInput ref={(input) => { this.textInput = input; }} /> ); } }
14.更改启动端口(VSCode)
{ "scripts": { "start": "set PORT=9000 && roadhog server",//加入set PORT=9000 && }, }
15.react.dva的使用
典型的一个dva应用。
import dva from 'dva'; import React from 'react'; import dva, { connect } from 'dva'; import './style.css'; // 1. Initialize const app = dva(); // 2. Model app.model({ namespace: 'count', state: 0, reducers: { add (count) { return count + 1 }, minus(count) { return count - 1 }, }, }); class TestError extends React.Component { componentDidCatch(e) { alert(e.message); } componentDidMount() { // throw new Error('a'); } render() { return <div>TestError</div> } } // 3. View const App = connect(({ count }) => ({ count }))(function(props) { return ( <div> <TestError /> <h2>{ props.count }</h2> <button key="add" onClick={() => { props.dispatch({type: 'count/add'})}}>+</button> <button key="minus" onClick={() => { props.dispatch({type: 'count/minus'})}}>-</button> </div> ); }); // 4. Router app.router(() => <App />); // 5. Start app.start('#root');
一共须要五步就能搭建一个囊括react、react-router、react-redux的应用。
① const app = dva();
能够往里传入各类初始化数据,hook之类的,好比:
initialState: { products: [ { name: 'dva', id: 1 }, { name: 'antd', id: 2 }, ], },
② app.model();
接收一个json数组,当中三个值:
const modelsCombine=[ { namespace: 'count', state: 0, reducers: { add (count) { return count + 1 }, minus(count) { return count - 1 }, }, }, { namespace: 'products', state: [], reducers: { 'delete'(state, { payload: id }) { return state.filter(item => item.id !== id); }, }, } ] modelsCombine.forEach(m=>app.model(m))
③ const App = connect()();
通常来讲,一个页面须要一个model和一个connect()就够了,这里的connect()能够剥离成独立文件,在路由配置中注册好就行,不须要堆在一块儿。
product.js:
import React from 'react'; import { connect } from 'dva'; import ProductList from '../components/ProductList'; const Products = ({ dispatch, products }) => { function handleDelete(id) { dispatch({ type: 'products/delete', payload: id, }); } return ( <div> <h2>List of Products</h2> <ProductList onDelete={handleDelete} products={products} /> </div> ); }; // export default Products; export default connect(({ products }) => ({ products, }))(Products);
④ app.router();
写一个独立的路由配置就够了。
app.router(require('./router').default); //router.js import React from 'react'; import { Router, Route, Switch } from 'dva/router'; import MainPage from './components/MainPage'; import SecondPage from './components/SecondPage'; import Countor from './routers/Countor'; import Products from './routers/Products'; function RouterConfig({ history }) { return ( <Router history={history}> <Switch> <Route path="/" exact component={MainPage} /> <Route path="/SecondPage" exact component={SecondPage} /> <Route path="/Countor" exact component={Countor} /> <Route path="/Products" exact component={Products} /> </Switch> </Router> ); } export default RouterConfig;
⑤ app.start('#root');
启动。
官方项目分层大体如此:
16.代理
package.json中
"proxy": "http://localhost:8080/"