React总结

1.脚手架

npm install -g create-react-app

使用方法:create-react-app XXX(项目名称),会自动init并install好项目,直接npm start就好了。

react-scripts 是什么?

react-scriptscreate-react-app生成项目所有的依赖。
通常情况下,我们创建spa应用时是使用npm安装项目依赖,在通过配置webpack.config.js进行配置,搭建好环境后在src编写源代码。而create-react-app是自动构建,在package.json中只有react-scripts作为依赖,而在reacr-scripts中已经配置好了项目所有需要的。另外,关于webpack.config.js,需要使用eject命令导出。

引用:https://blog.csdn.net/qq_22889599/article/details/79507721

引用:https://www.jianshu.com/p/c6040430b18d
 
2.react处理Enter事件
<input type="text" onKeyUp={this.EnterData.bind(this)} />
  EnterData(event){
    const {textBox} = this.state;
    if(event.keyCode==13){  
      this.setState(
        {textBox:textBox.concat(event.target.value)}
      );
      }
    }

3.setState与States

    this.state={
      textBox:[]
    }
      this.setState(
        {textBox:textBox.concat(event.target.value)}
      );

但是使用的时候,依然需要:

const {textBox} = this.state;

先取下来再进行数据操作。

4.CSS元素使用

    let diagramContainer={
        padding: '20px',
         window.innerWidth,
        height: window.innerHeight,
        border: '1px solid gray'
    };
<div className="Dotcon" style={diagramContainer}>
<div id={pid} style={{position:'absolute',height:'80px','80px',border:'1px solid blue',color:'blue',float:'left',left:pleft,top:ptop}}>{pid}</div>

5.字符串连接

var name1 ="Mike";
var age1=20;
var message1=`hello,${name1},your age is ${age1}`;

6.JS数组CRUD

追加:

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>
    );
    //子组件调用父组件传进来的方法,进行回调,并传回一个值。

引用:https://www.cnblogs.com/lixuemin/p/5754289.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值
  textBox.map((text,index)=>{
  return <AddText key={text} Text={text} Index={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可以做到跨组件数据同步,而不需要将数据先一步步传递给父组件,再传递给另一个子组件。如果加上@解释器,会更加优雅。


13.ref的使用
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数组,当中三个值:

namespace 表示在全局 state 上的 key
state 是初始值
reducers 等同于 redux 里的 reducer,接收 action,同步更新 state。
一般来讲可以把这组值抽取出去变成一个特定的数组,一起引入即可。
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/"

原文地址:https://www.cnblogs.com/chrisweiii/p/10529874.html