React初尝

React 是什么

React 是构建 UI 组件的 JS 库,专注于做 mvc 中的 v。

为什么使用React

  • api 少, 类库易学
  • 组件内聚,易于组合
  • 原生组件和自定义组件融合
  • 状态/属性驱动全局更新
  • commonjs 生态圈/工具链完善

JSX

类似 xml 的语言,用来描述组件树

<div className = "x">
    <a href="#">#</a>
    <component x="y">...</component>
</div>
React.createElement('div', {
className: 'x'},[
React.createElement('a', {href:'#'}, '#'),
React.createElement(Component, {x: 'y'}, 1),
]
);

注意和 html 语法不太一样,必须是驼峰命名,以及属性名不能和 js 关键字冲突,例如: className, readOnly

可以通过 {变量名} 来将变量的值作为属性值

可以通过 {…obj} 来批量设置一个对象的键值对到组件的属性,注意顺序

var x = 'http://www.alipay.com';
var obj = {
    href:"http://www.taobao.com",
    target:"_blank"
}

var y = <a {...obj} href={x}>alipay.com</a>
React.render(y, document.getElmentById('container'));

最简单的 react 组件

Hello World Demo
<html>
  <head>
  	 <meta content="text/html;charset=UTF-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
     <!-- 生产环境中不建议使用 -->
     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="container"></div>

    <script type="text/babel">
        class HelloMessage extends React.Component {
            constructor(props) {
                super(props);
                this.state = {name: ''};
            }
            
            render() {
                return (
                    <div>Hello {this.props.name}!</div>
                );
            }
        }

        ReactDOM.render(
            <HelloMessage name="Word"/>,
            document.getElementById('container')
        );
    </script>
  </body>
 </html>

用状态控制组件变化

定时器 Demo

可以把一个组件看作一个状态机,每一次状态对应于组件的一个 UI

<html>
  <head>
  	 <meta content="text/html;charset=UTF-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
     <!-- 生产环境中不建议使用 -->
     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="container"></div>

    <script type="text/babel">
        class Timer extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    secondsElapsed: 0
                };
            }

            tick() {
                this.setState({
                    secondsElapsed: this.state.secondsElapsed + 1
                });
            }

            componentDidMount() {
                this.interval = setInterval(() => this.tick(), 1000);
            }
            
            componentWillUnmount() {
                clearInterval(this.interval);
            }

            render() {
                return (
                    <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
                );
            }
        }

        ReactDOM.render(
            <Timer />,
            document.getElementById('container')
        );
    </script>
  </body>
 </html>

Event

可以通过设置原生 DOM 组件的 onEventType 属性来监听 DOM 事件,例如 onClick, onMouseDown, 在加强组件内聚性的同时,避免了传统 html 的全局变量污染

组合

可以像使用原生 DOM 组件一样使用自定义的组件

var A = React.createClass({
   render(){
       return <a href='#'>a</a>
   } 
});

var B = React.createClass({
   render() {
       return <i> <A />! </i>
   } 
});

React.render(<B />, document.getElementById('container'));

组合Children

var B = React.createClass({
   render(){
     return <ul> 
        { React.Children.map(this.props.children, function(c)){
                return <li>{C}</li>
            }
        }
     </ul> 
   } 
});

React.render(
    <B> 
        <a href="#">1</a>
        2
    </B>,
    document.getElementById('container'));
)

props

通过 this.props 可以获取传递给该组件的属性值,还可以通过定义 getDefaultProps 来指定默认属性值

var B = React.createClass({
   getDefaultProps(){
       return {
           title: 'default'
       };
   },
   render() {
       return <b>{this.props.title}</b>
   }
});


React.render(
    <div>
        <B title="指定"></B>
    </div>, docuemnt.getElementById('container');
)

prop validation

通过指定 propTypes 可以校验属性的类型

var B = React.createClass({
    propTypes: {
        title: React.PropTypes.string,
    },
    render() {
        retrun <b>{this.props.title}</b>
    }
})

state

组件内部的状态,可以使用 state

class Hello extends Component{
    constructor(props){
        super(props);
        this.state= {
            name:"hello world"
        }
    }
    
    render() {
        return (
            <div>{this.state.name}</div>
        )
    }
    
}

Mixin

Mixin 是一个普通对象,通过 mixin 可以在不同组件间共享代码

var A = React.createClass

Form

和 html 的不同点

  • value/checked 属性设置后,用户输入无效
  • textarea 的值要设置在 value 属性
  • select 的 value 属性可以是数组,不建议使用 option 的 selected 属性
  • input/textarea 的 onChange 用户每次输入都会触发(即使不失去焦点)
  • redio/checkbox 点击后触发 onChange

如果设置了 value 属性,那么该组件变为受控组件,用户无法输入,除非程序改变 value 属性。可以通过监听 onChange 事件结合 state 来改变 input 的值

Ref

该功能是为了结合现有非 react 类库,通过 ref/refs 可以取得组件实例,进而取得原生节点

Component API

React.createClass 定义组件时允许传入的配置

  • getDefaultProps 得到默认属性对象
  • propTypes 属性检测规则
  • mixins 组件间公用方法

Component lifecycle

React.createClass 定义时允许传入的函数,会在特定生命周期内调用

初次创建组件时调用
  • getInitialState 得到初始状态对象
  • render 返回组件树,必须设置
  • componentDidMount 渲染到 dom 树中时调用,只在客户端调用,可用于获取原生节点
组件属性值改变时调用
  • componentWillReceiveProps 属性改变调用
  • shouldComponentUpdate 判断是否需要重新渲染
  • render 返回组件树,必须设置
  • componentDidUpdate 渲染到 dom 树中时调用,可用于获取原生节点
  • 最后是 componentWillUnmount 组件,从 dom 销毁前调用

一步步搭建 React 应用


<html>
  <head>
  	 <meta content="text/html;charset=UTF-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
     <!-- 生产环境中不建议使用 -->
     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="container"></div>

    <script type="text/babel">

        class Comment extends React.Component {
            constructor(props) {
                super(props);
            }

            render() {
                return (
                    <div>
                        <h2>{this.props.author}</h2>
                        {this.props.text}
                    </div>
                );
            }
        }

        class CommentList extends React.Component {
            constructor(props) {
                super(props);
            }

            render() {
                return (
                        this.props.data.map((item, index)=> (
                            <Comment key ={index} author={item.author} text={item.text}></Comment>
                        ))
                );
            }
        }

        class CommentForm extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
         
                };
            }

            render() {
                return (
                    <div>
                        作者:<input type="text" value={this.state.author} onChange={this.props.handleAuthorOnchange}/>
                        评论:<input type="text" value={this.state.text} onChange={this.props.handleTextOnchange}/>
                        <input type="button" value="提交" onClick={this.props.handleOnClick}/>
                    </div>
                );
            }
        }

        class CommentBox extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    author: '作者',
                    text: '评论',
                    data: [
                        {author: "作者1", text: "评论1"},
                        {author: "作者2", text: "评论2"}
                    ]
                };
                this.handleAuthorOnchange = this.handleAuthorOnchange.bind(this);
                this.handleTextOnchange = this.handleTextOnchange.bind(this);
                this.handleOnClick = this.handleOnClick.bind(this);
            }
            
            handleAuthorOnchange(event) {
                const author = event.target.value;
                this.setState({ author: author });
            }

            handleTextOnchange(event) {
                const text = event.target.value;
                this.setState({ text: text });
            }

            handleOnClick() {
                console.log("1111");
                const author = this.state.author;
                const text = this.state.text;
                console.log("author: " + author + ", text: " + text);

                this.setState(prevState => ({
                    data: [...prevState.data, {author:author, text:text}]
                }));
            }

            render() {
                return (
                    <div>
                        <h1>Coments</h1>
                        <CommentList data={this.state.data} />
                        <CommentForm handleOnClick={this.handleOnClick}
                             handleAuthorOnchange={this.handleAuthorOnchange} handleTextOnchange={this.handleTextOnchange}/>
                    </div>
                );
            }
        }

        ReactDOM.render(
            <CommentBox />,
            document.getElementById('container')
        );
    </script>
  </body>
 </html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值