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/"