react学习笔记

1.生命周期

getDefaultProps 初始化Props    设置组件属性的默认值,通过组件的getDefaultProps方法



componentWillMount 在渲染前调用,在客户端也在服务端。

componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。

componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 
可以在你确认不需要更新组件时使用。

componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。

componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。

 

 

 

2.绑定事件

【1】

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

 

【2】

 

 

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }
  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

【3】

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

 

3.事件传递

react 16.8.6 以上:
<Button type={this.state.lighting.dl} onClick={this.lightingOperation("dl")}>



  /**
   * 开关操作
   * @param {string} 灯光类型
   */
  lightingOperation = type => e => {
    console.log("开关操作", type, this.state.lighting[type]);
    let cmd = "open";
    if (this.state.lighting[type] == "primary") {
      cmd = "close";
    }
    this._ws.send({ CMD: cmd, ROOMID: this.state.room, DEVID: "AllLamp" });
    let lighting = { ...this.state.lighting };
    lighting[type] = cmd == "open" ? "primary" : "";
    this.setState({
      lighting: lighting
    })
  }

 

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

 

class Popper extends React.Component{
    constructor(){
        super();
        this.state = {name:'Hello world!'};
    }
    
    preventPop(name, e){    //事件对象e要放在最后
        e.preventDefault();
        alert(name);
    }
    
    render(){
        return (
            <div>
                <p>hello</p>
                {/* Pass params via bind() method. */}
                <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
            </div>
        );
    }
}

4.组件传值

【父】===》【子】(props)

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

ES6

class Welcome extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
    <h1>Hello, {this.props.name}</h1>
    );
  }
}
const element = <Welcome name="Sara1" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

【子】==》【父||兄】(状态提升)(类似vue中的$emit和$on)

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


function toCelsius(fahrenheit) {
  return (fahrenheit - 32) * 5 / 9;
}


function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}


function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}


function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}


class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }


  handleChange(e) {
    this.props.onTemperatureChange(e.target.value);
  }


  render() {
    const temperature = this.props.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}


class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};
  }


  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }


  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});
  }


  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;
    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;


    return (
      <div>
        <TemperatureInput
          scale="c"
          temperature={celsius}
          onTemperatureChange={this.handleCelsiusChange} />
        <TemperatureInput
          scale="f"
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} />
        <BoilingVerdict
          celsius={parseFloat(celsius)} />
      </div>
    );
  }
}


ReactDOM.render(
  <Calculator />,
  document.getElementById('root')
);

以上关键:

  onTemperatureChange={this.handleFahrenheitChange}

  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }

  handleChange(e) {
    this.props.onTemperatureChange(e.target.value);
  }

5.react组合(类似vue中的slot)

 function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}
//组件
class Layout extends React.Component {
    render() {
        console.log(this.props);
        return (
            <section>
                <Link to="/home">{this.props.msg}</Link>
                <div className="left">
                    {
                        this.props.children[0]
                    }
                </div>
                <div className="right">
                    {
                        this.props.children[1]
                    }
                </div>
                <Hfooter></Hfooter>
            </section>
        )
    }
}
export default Layout;

class Home extends React.Component {
    render() {
        return (
            <section>
                <Layout msg="">
                 <div className="fv" key="left">hhhh</div>
                 <div className="fv" key="right">hhh3333h</div>
                </Layout>
            </section>
        )
    }
}
export default Home;




或者

class Home extends React.Component {
    render() {
        var leftHtml='<div className="fv" key="left">hhhh</div>';
        return (
            <section>
                <Layout msg="" left={leftHtml}>
                 <div className="fv" key="left">hhhh</div>
                 <div className="fv" key="right">hhh3333h</div>
                </Layout>
            </section>
        )
    }
}
export default Home;

class Layout extends React.Component {
    render() {
        console.log(this.props);
        return (
            <section>
                <Link to="/home">{this.props.msg}</Link>
                <div dangerouslySetInnerHTML={{ __html: this.props.left }}  />
                <div className="left">
                    {
                      this.props.left
                    }
                </div>
                <div className="right">
                    {
                        this.props.children[1]
                    }
                </div>
                <Hfooter></Hfooter>
            </section>
        )
    }
}
export default Layout;

【指定显示位置】

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

 

6.条件渲染 动态绑定

 

<div>
  {showHeader && <Header />}
  <Content />
</div>

条件渲染<Header />组件

6.1动态绑定属性

eg:动态绑定disable属性

 <Button disabled={this.state.disabled} onClick={this.sendSms} type="primary">{state.btnTxt}</Button>

6.2 样式绑定 : https://blog.csdn.net/suwyer/article/details/81481507

 

 

 

/*这个方法名称是已经定义好的,不能改名称。用于定义初始状态*/
getInitialState:function(){
       return {redorblue:this.props.defaultColor};
},

这个是使用react.createClass创建组件时使用的

 

 

20180719

jsx 

1.只能有一个根节点,类似vue.

2.jsx中的注释

{}中可以写js代码

所有注释: {/**/}

3.在jsx中样式class要改成className 因为class是js中类的关键字,属于保留字。

eg:

<div className="title">11111</div>

4.行内样式

<div style={{fontSize:'30px',display:'block'}}>11111</div>

为什么要用两个大括号

第一个大括号是包裹,里面写js变量等

可以按下面的理解

var s={
    fontSize:'30px',
    display:'block'
}
<div style={s}>11111</div>

5.事件

见上方

 

6.循环渲染

class Hello extends React.Component {

   render(){
      var arr=[1,2,3,4,5,6,7]
      return{
            <div>
              {
                arr.map((v,i)=>{
                   return <p key={i}>{v}</p>
                })
              }
            </div>
      }
   }
}

以上使用map不可使用forEach,因为map可以有返回值,forEach没有返回值

react和vue 循环时的key是为了下次渲染时加快效率,可以按数据库索引来理解

循环内嵌条件渲染
   <div style={{ flex: '7', marginLeft: "13%" }}>
          {
            Object.keys(this.state.roomObj).map((key) => {
              return (
                <div key={key}>
                  <List
                    rowKey={key}
                    grid={{
                      gutter: 0,
                      xl: 10,
                      lg: 5,
                      md: 5,
                      sm: 5,
                      xs: 5,
                    }}
                    loading={loading}
                    dataSource={this.state.roomObj[key]}
                    renderItem={item => (
                      <List.Item key={item.roomid} className={styles.resetListItemMargin}>
                        <Card
                          onClick={this.roomInfo(item.roomid)}
                          hoverable
                          size="small"
                          className={item.member > 0 ? styles.resetMarginColor : styles.resetMargin}
                          actions={[
                            <Tooltip key="member" title="人数" >
                              <IconFont className={styles.resetFont} type="icon-renshu" style={{ color: item.member > 0 ? '#1890ff' : 'grey' }} />
                            </Tooltip>,
                            <Tooltip key="light" title="灯光">
                              <IconFont className={styles.resetFont} type="icon-dengguang" style={{ color: item.light === true ? '#1890ff' : 'grey' }} />
                            </Tooltip>,
                            <Tooltip key="airConditioner" title="空调" >
                              <IconFont className={styles.resetFont} type="icon-kongtiao" style={{ color: item.airConditioner === true ? '#1890ff' : 'grey' }} />
                            </Tooltip>,
                            <Tooltip key="curtain" title="窗帘">
                              <IconFont className={styles.resetFont} type="icon-chuanglian" style={{ color: item.curtain === true ? '#1890ff' : 'grey' }} />
                            </Tooltip>
                          ]}
                        >
                          <div className={styles.cardItemContent}>
                            <CardInfo
                              roomid={item.roomid}
                              temperature={item.temperature}
                              sos={item.sos === true ? 'red' : 'grey'}
                            />
                          </div>
                        </Card>
                      </List.Item>
                    )}
                  />
                  {
                    key == Object.getOwnPropertyNames(this.state.roomObj).length || <hr />
                  }
                </div>
              )
            })
          }
        </div>

7.代码分离

 

9数据传递

使用组件时传递参数:

import Header from '../compentes/Header'
class Hello extends React.Component {

   render(){
      var arr=[1,2,3,4,5,6,7];
      var obj={a:1234,b:"你好"}
      return{
            <div>
              <Header title="this is header" mHeader={obj} ></Header>
              {
                arr.map((v,i)>{
                   return <p key={i}>{v}</p>
                })
              }
           
            </div>
      }
   }
}

//组件
class Header extends React.Component {
   render(){
      return{
            <div>
              <p>{this.props.title}</p>
              <p>{this.props.mHeader.a}</p>
            </div>
      }
   }
}
export default Header;

10.区别开发环境和生产环境

if(_DEV_){
  //开发环境下执行
}

11类似vue中的router-view,做布局页

class App extends React.Component {
   render(){
      return{
            <div>
                  <div>header自定义头部</div>
                  <P>{this.pprops.children}</p>
                  <div>footer自定义底部</div>
            </div>
      }
   }
}
export default App

12.路由配置文件

<Route path="/loginPass/:phone?" component={asyncLoad(() => import('../views/login/loginPass'), "")} />

类似vue   在path中加参数时有?的话,就表示:后面的值不是必须的,可以为空

13es6条件渲染

class Hheader extends React.Component {
    render() {
        return (
            <div className="Hheader">
                {
                    this.props.header.lTxt ? <div className="left" onClick={this.goBack.bind(this)}>{this.props.header.lTxt}</div> : ""
                }
                <div className="center">{this.props.header.title}</div>
                <div className="right">{this.props.header.rTxt}</div>
            </div>
        )
    }
    goBack(){
        
    }
}

export default Hheader;

14.自定义组件样式设置

//组件
class Hscroll extends React.Component{
  render(){
    console.log(this.props)
      return(
          <div className={this.props.className}>
               {
                   this.props.children
               }
          </div>
      )
  }
}
 <Hscroll className="has-header has-footer">
 </Hscroll>


 class Hscroll extends React.Component{
     render(){
       console.log(this.props)
         return(
             <div className={this.props.className.join(" ")}>
                  {
                      this.props.children
                  }
             </div>
        )
     }
  }

<Hscroll className={['has-header','has-footer']}>
 </Hscroll>

15.引入ant-mobile

安装依赖

npm install antd-mobile --save

入口文件引用样式文件
//引入and-mobile 样式
import 'antd-mobile/dist/antd-mobile.css';

局部组件使用

import { Button, List, InputItem, WhiteSpace } from 'antd-mobile';

未解决问题:按需加载

16.使用getFieldProps

import React from 'react';
import ReactDOM from 'react-dom';
import '../../assets/css/basic.scss';
import './login.scss';
//组件
import Hheader from '../../components/hheader/index';
import Hscroll from '../../components/hscroll/index';

import { Button, List, InputItem, WhiteSpace } from 'antd-mobile';
import { createForm } from 'rc-form';
class Login extends React.Component {
    render() {
        const { getFieldProps } = this.props.form;
        return (
            <div className="login">
                <Hheader header={{ title: "登录", lTxt: "返回", url: '/home' }} />
                <Hscroll className="has-header has-footer">
                    <img className="login_logo" src="/img/login_logo.png" alt="" />
                    <List renderHeader={() => ''} className="login-input">
                        <InputItem  {...getFieldProps('phone')} type="phone"><i className="iconfont icon-shouji1"></i></InputItem>
                    </List>

                    <Button type="primary" className="login-btn">登录</Button>
                </Hscroll>

            </div>
        )
    }
}
const LoginForm = createForm()(Login);//重要,否则会报找不到getFieldProps
export default LoginForm;

或者
export default createForm()(Login);

17.获取使用getFieldProps用户输入的值,input取值

let userInfo = this.props.form.getFieldsValue();
console.log(userInfo);

----{phone:15757801424}

17.1 普通非受控组件取值

我们推荐使用 受控组件 来实现表单。 在受控组件中,表单数据由 React 组件处理。如果让表单数据由 DOM 处理时,替代方案为使用非受控组件。

受控组件和非受控组件的区别就是数据是否由react处理,非受控组件的数据通过ref用DOM来处理
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>
        )
    }
}

---------------------

本文来自 Pinkh 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Shuiercc/article/details/81383679?utm_source=copy 

使用defaultValue表示组件的默认状态,此时它只会被渲染一次,后续的渲染不起作用;input的值不随外部的改变而改变,由自己状态改变。


zjeg:

 handleOk(e) {
        console.log( this.input.refs.input.value);
        this.setState({
            code:this.input.refs.input.value
        });
    },

  <Modal className="hModal"
                    title="请输入验证码"
                    visible={this.state.visible}
                    onOk={this.handleOk}
                    onCancel={this.handleCancel}>
                    <br />
                    <Row>
                        <Col span={18}> <Input ref={(input) => this.input = input} placeholder="请输入验证码" /></Col>
                        <Col span={5} offset={1}> <Button disabled={state.disabled} onClick={this.sendSms} type="primary">{state.btnTxt}</Button></Col>
                    </Row>
                    <br />
                </Modal>

17.2 受控组件

import React , {Component} from 'react';
export default class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            inpValu:''
        }
    }

    handelChange(e){
        this.setState({
            inpValu:e.target.value
        })
    }

    render(){
        return(
            <div>
                <input type="text" onChange={this.handelChange.bind(this)} defaultValue={this.state.inpValu}/>
            </div>
        )
    }
}

input 输入框的值会随着用户输入的改变而改变,onChange通过对象e拿到改变之后的状态并更新state,setState根据新的状态触发视图渲染,完成更新。

使用form取值

 

import React from 'react'
import {
  Form,
  Row,
  Select,
  Input,
  Col
} from 'antd';

const createForm = Form.create;
const FormItem = Form.Item;

let ExceptionBehaviorlist = React.createClass({

     render() {
        const {
          getFieldProps
        } = this.props.form;

        return(
         <Modal ref="hmodal" title="确认操作" maskClosable={false} destroyOnClose={true} onCancel={this.hideModal} onOk={this.handleOk} visible={state.visible} width="520" >
          <Form horizontal>
            <Row>
              <Col span="24">
                <FormItem label="状态:">
                  <Select {...getFieldProps('state')} defaultValue="" style={{ width: 480 }}>
                    <Option value="20">正常</Option>
                    <Option value="30">异常</Option>
                  </Select>
                </FormItem>
              </Col>
            </Row>
            <Row>
              <FormItem label="备注">
                <textarea {...getFieldProps('remark', { initialValue: '' })} style={{ width: 480, height: 100 }}>

                 </textarea>
                {/* <Input  {...getFieldProps('remark', { initialValue: '' })} style={{ width: 420, height: 100 }} /> */}
              </FormItem>
            </Row>
          </Form>
        </Modal>

        )
     }

})


取值:
 handleOk() {
    var params = this.props.form.getFieldsValue();
  },
赋值:
this.props.form.setFieldsValue({
      state: record.state,
      remark: record.remark
    })

 

 

18.路由js跳转和参数传递

1.普通跳转
this.props.history.push({ pathname:'/loginPass'});

 

19.某些配置的react不会自动更新

目录太深,改浅一点就好了


*******************************************************************************************************************************

使用 ant design

1.创建表单

import {Form,Row,Col,Select,Input} from 'antd';

const createForm = Form.create;
const FormItem = Form.Item;

var AdjustRecord = React.createClass({

 render() {
        const { getFieldProps, getFieldValue } = me.props.form; 

      return (

                    <Form form={this.props.form}>
                        <Row>
                            <FormItem {...formItemLayout} label="状态:">
                                <Select defaultValue="1" style={{ width: 120 }} onChange={this.handleChange}>
                                    <Option value="1">同意</Option>
                                    <Option value="2">拒绝</Option>
                                </Select>
                            </FormItem>
                        </Row>
                        {state.value != 2 ? "" :
                            <Row><FormItem {...formItemLayout} label="备注:">
                                <Input placeholder="请输入拒绝备注"  {...getFieldProps('reason', { rules: [{ required: true, message: '必填' }] })} />
                            </FormItem>
                            </Row>
                        }
                    </Form>
            </div>
        );
  
 }
AdjustRecord = createForm()(AdjustRecord);
export default AdjustRecord

20.pc端 页面滚动加载,瀑布式,页面上拉加载更多

npm install react-infinite-scroller



 <InfiniteScroll
                            initialLoad={false}
                            // pageStart={0}
                            loadMore={this.handleInfiniteOnLoad}
                            hasMore={state.hasMore&&!state.loading}
                            useWindow={false}>
                            <Table columns={columns2} rowKey={this.rowKey}
                                dataSource={this.state.dataTrade}
                                pagination={false} />
                        </InfiniteScroll>


 //加载更多
    handleInfiniteOnLoad() {
        let me = this;
        let current = me.state.current;
        if (current > this.state.totalPage) {
            console.log(current, "<><我是有底线的><>", this.state.totalPage);
            message.info("我是有底线的");
            return;
        }
        me.setState({
            current: current + 1
        }, () => {
            me.pagefetch({
                current: me.state.current,
                pageSize: me.state.pageSize
            });
        })
    },

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值