React语法入门中

<div ></div><!--html元素或需要被操作的元素-->
<script type="text/babel">
    /*创建标签名字第一个字母大写*/
    var Helloworld = React.createClass({
        render:function(){
            return (<div>hello world</div>);
        }
    });
    /*ReactDOM.render 是 React 的最基本方法,用于将模板(html,jsx,React.createElement等)转为 HTML ,并插入指定的 DOM 节点。*/
    ReactDOM.render(<Helloworld/>,document.getElementById('demo'),,function(){
        console.log('执行成功之后的回调函数');
    });
</script>

Demo1

    <div ></div>
    <div ></div>
    <script type="text/babel">
        var Helloreact = React.createClass({
            render:function(){
                return (<div>hello react</div>);
            }
        });
        var Helloworld = React.createClass({
            render:function(){
                var reacts = [];
                for(var i=0;i<10;i++){
                    reacts.push(<Helloreact key={'Helloreact'+i}/>);
                }
                return (
                    <div>
                        <div>hello world</div>
                        {reacts}
                    </div>);
            }
        });
        var demos = ['demo1','demo2','demo3'];
        ReactDOM.render(
            <Helloworld/>,
            document.getElementById("app"),
            function(){
                console.log('success');
            }
        );

        ReactDOM.render(
            <div>
                {demos.map(function(demo){
                    return (<div key={'demo'+demo}>Hello {demo}</div>);
                })
                }
            </div>,document.getElementById('demo'),function(){
                console.log('success');
            }
        );
    </script>

Demo2

    <div ></div>
    <script type="text/babel">
        var ClickDemo = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            getInitialState:function(){
                return {clickCount:0};
            },
            clickFun:function(){
                /*this.setState是更新state中的参数,执行实时更新组件的方法*/
                return this.setState({clickCount:this.state.clickCount + 1});
            },
            render:function(){
                return (
                    <div>
                        <div>共点击了{this.state.clickCount}</div>
                        <button onClick={this.clickFun}>点我</button>
                    </div>);
            }
        });
        ReactDOM.render(<ClickDemo/>,document.getElementById('demo'));
    </script>

Demo3

    <div ></div>
    <script type="text/babel">
        var MessageBox = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            getInitialState:function(){
                return {
                    isVisible:true,
                    title:'你好react',
                    subMessages:['码代码可以改变世界','码代码是上帝创造的鬼斧神工','码代码可以走向人生巅峰']
                }
            },
            render:function(){
                /*
                    <Helloreact messages={this.state.subMessages}/> 这是将当前组件中的state的subMessages数组传入到Helloreact组件中去,
                    messages是传入props的属性名
                */
                return (
                    <div>
                        <div>{this.state.title}</div>
                        <Helloreact messages={this.state.subMessages}/>
                    </div>

                )
            }
        });
        var Helloreact = React.createClass({
            /*
                这是设置当前默认的messages数组,如果前面组件未传入参数进来就取默认的
            */
            getDefaultProps:function(){
                return {messages:['默认喜欢码代码']}
            },
            render:function(){
                /*
                    React中的每一个组件,都包含有一个属性(props),属性主要是从父组件传递给子组件的,在组件内部,我们可以通过this.props获取属性对象
                    react官方认为,props应该是只读的,不应该被修改。因为 React 不能帮你检查属性类型(propTypes)。这样即使你的 属性类型有错误也不能得到清晰的错误提示。
                    Props 应该被当作禁止修改的。修改 props 对象可能会导致预料之外的结果,所以最好不要去修改 props 对象。
                */
                var msgs = [];
                /*
                    map():返回一个新的Array,每个元素为调用func的结果
                    forEach():没有返回值,只是针对每个元素调用func
                */
                this.props.messages.forEach(function(msg,index){
                    msgs.push(<p key={index}>码农说:{msg}</p>);
                });
                return (<div>{msgs}</div>);
            }
        });
        ReactDOM.render(<MessageBox/>,document.getElementById('demo'));
    </script>

Demo4

    <div ></div>
    <script type="text/babel">
        var FormApp = React.createClass({
            getInitialState:function(){
                return {
                    inputValue:'this is inputValue',
                };
            },
            changeFunc:function(e){
                this.setState({
                    /*设置当前state中inputValue的值是该html元素对象的value值*/
                    inputValue:e.target.value
                });
            },
            submitFunc:function(e){
                e.preventDefault();/*阻止默认事件*/
                console.log('form is submiting......');
                console.log(e);
            },
            render:function(){
                /*
                    表单属性中defaultValue属性和value的区别
                    defaultValue是默认值,第一次设置时生效,手动输入值时允许被改变
                    value是当前input的值,手动输入值不会被改变
                    如果需要改变当前value的值则需要使用onChange事件来改变其中this.state.inputValue的值
                */
                return (
                    <form onSubmit={this.submitFunc} action="" method="post">
                        <input type="text" defaultValue={this.state.inputValue}/><br/><br/><br/>
                        <input type="text" onChange={this.changeFunc} value={this.state.inputValue}/><br/><br/><br/>
                        <button type="submit">提交一下</button>
                    </form>
                    );
            }
        });
        ReactDOM.render(<FormApp/>,document.getElementById('demo'));
    </script>

Demo5

    <div ></div>
    <script type="text/babel">
        var FormApp = React.createClass({
            getInitialState:function(){
                return {
                    inputValue:'this is inputValue',
                };
            },
            changeFunc:function(e){
                this.setState({
                    /*设置当前state中inputValue的值是该html元素对象的value值*/
                    inputValue:e.target.value
                });
            },
            submitFunc:function(e){
                e.preventDefault();/*阻止默认事件*/
                console.log('form is submiting......');
                /*
                    ref是React中的一种属性,当render函数返回某个组件的实例时,可以给render中的某个虚拟DOM节点添加一个ref属性
                    ref 属性
                    React 支持一种非常特殊的属性,你可以用来绑定到 render() 
                    输出的任何组件上去。这个特殊的属性允许你引用 render() 返回的相应的支撑实例
                    ( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
                    下面4种方式都可以通过ref获取真实DOM节点
                    var usernameDOM = this.refs.username.getDOMNode();
                    var usernameDOM = React.findDOMNode(this.refs.username);
                    var usernameDOM = this.refs['username'].getDOMNode();
                    var usernameDOM = React.findDOMNode(this.refs['username']);
                */
                console.log(this.refs['goodInput']);//返回dom节点
                /*console.log(this.refs['goodInput'].getDOMNode());无法调用*/
                console.log(this.refs['goodInput'].value);//返回input节点下的value值
            },
            render:function(){
                /*
                    表单属性中defaultValue属性和value的区别
                    defaultValue是默认值,第一次设置时生效,手动输入值时允许被改变
                    value是当前input的值,手动输入值不会被改变
                    如果需要改变当前value的值则需要使用onChange事件来改变其中this.state.inputValue的值
                */
                return (
                    <form onSubmit={this.submitFunc} action="" method="post">
                        <input type="text" defaultValue={this.state.inputValue}/><br/><br/><br/>
                        <input type="text" ref="goodInput" defaultValue={this.state.inputValue}/><br/><br/><br/>
                        <button type="submit">提交一下</button>
                    </form>
                    );
            }
        });
        ReactDOM.render(<FormApp/>,document.getElementById('demo'));
    </script>

Demo6

    <div ></div>
    <script type="text/babel">
        var FormApp = React.createClass({
            getInitialState:function(){
                return {
                    inputValue:'this is inputValue',
                    radioValue:'C',
                    textareaValue:'this is textareaValue'
                };
            },
            changeFunc:function(e){
                this.setState({
                    /*设置当前state中inputValue的值是该html元素对象的value值*/
                    inputValue:e.target.value
                });
            },
            submitFunc:function(e){
                e.preventDefault();/*阻止默认事件*/
                console.log('form is submiting......');
                /*
                    ref是React中的一种属性,当render函数返回某个组件的实例时,可以给render中的某个虚拟DOM节点添加一个ref属性
                    ref 属性
                    React 支持一种非常特殊的属性,你可以用来绑定到 render() 
                    输出的任何组件上去。这个特殊的属性允许你引用 render() 返回的相应的支撑实例
                    ( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
                    下面4种方式都可以通过ref获取真实DOM节点
                    var usernameDOM = this.refs.username.getDOMNode();
                    var usernameDOM = React.findDOMNode(this.refs.username);
                    var usernameDOM = this.refs['username'].getDOMNode();
                    var usernameDOM = React.findDOMNode(this.refs['username']);
                */
                /*console.log(this.refs['goodInput']);返回dom节点*/
                /*console.log(this.refs['goodInput'].getDOMNode());无法调用*/
                /*console.log(this.refs['goodInput'].value);返回input节点下的value值*/
                var formData = {
                    textInput:this.refs['goodInput'].value,
                    radioInput:this.state.radioValue,
                    textareaEle:this.refs['goodTextarea'].value
                }
                console.log(formData);
            },
            changeRadio:function(e){
                /**
                    每当radio改变时,设置其state属性值,那嵌套标签里加入一个函数,
                    子函数调用为this.props.func,标签引用func={this.func}
                */
                this.setState({
                    radioValue:e.target.value
                })
            },
            render:function(){
                /*
                    表单属性中defaultValue属性和value的区别
                    defaultValue是默认值,第一次设置时生效,手动输入值时允许被改变
                    value是当前input的值,手动输入值不会被改变
                    如果需要改变当前value的值则需要使用onChange事件来改变其中this.state.inputValue的值
                */
                return (
                    <form onSubmit={this.submitFunc} action="" method="post">
                        <input type="text" ref="goodInput" defaultValue={this.state.inputValue}/><br/><br/><br/>
                        <RadioBox ref="goodRadio" changeRadio={this.changeRadio}/>
                        this is textarea<br/>
                        <textarea ref="goodTextarea" name="goodTextarea" defaultValue={this.props.textareaValue}></textarea>
                        <button type="submit">提交一下</button>
                    </form>
                    );
            }
        });
        var RadioBox = React.createClass({
            render:function(){
                return (
                    <span>
                        A:
                        <input type="radio" onChange={this.props.changeRadio} name="goodRadio" value="A" /><br/>
                        B:
                        <input type="radio" onChange={this.props.changeRadio} name="goodRadio" value="B" /><br/>
                        C:
                        <input type="radio" onChange={this.props.changeRadio} name="goodRadio" defaultChecked value="C" /><br/><br/>
                    </span>
                    );
            }
        });
        ReactDOM.render(<FormApp/>,document.getElementById('demo'));
    </script>

Demo7

    <div ></div>
    <script type="text/babel">
        /*双向数据流*/
        var TwodTataFlow = React.createClass({
            /*
                LinkedStateMixin给你的React组件添加一个叫做linkState()的方法。linkState()
                返回一个ReactLink对象,包含ReactState当前的值和一个用来改变它的回调函数。
                ReactLink对象可以在树中作为props被向上传递或者向下传递
            */
            /*
                双向绑定的使用:
                组件需要mixins:引用LinkedStateMixin。它提供一个linkState方法。参数是state属性
                双向绑定用valueLink={this.linkState(XX)}
                linkState方法返回一个对象,有一个value属性,指定state的属性。
                还有一个requestChange回调方法,用来实现state的修改。参数是新值 
                可以理解成onchange的绑定方法。可以自己写一个linkState对象,
                value是state.XX requestChange里用setState()来修改值。用valueLink={obj}来实现。
                可以理解成this.linkState()实现的就是指定绑定值value 和change方法
                valueLink属性实现了linkstate.value绑定到value requestChange方法绑定onChange
                可以创建一个this.linkState('XX') value={XX.value} onchange={fn}方法内
                使用Xx.requestChange(e.target.value)
            */
            mixins:[React.addons.LinkedStateMixin],
            getInitialState:function(){
                return {
                    messages:'react is very good',
                    isReactBool:true
                }
            },
            render:function(){
                return (
                    <div>
                        <h1>ME说:{this.state.messages}</h1>
                        <h2>React is very good?{this.state.isReactBool?' yes':' no'}</h2>
                        <input type='text' valueLink={this.linkState('messages')}/>
                    </div>
                );
            }
        });

        /*
            不带ReactLink的LinkedStateMixin(ReactLink Without LinkedStateMixin)
            这个在处理input text文本框时使用valueLink是在其内部声明了一个
            valueLink方法,等同于是将这个方法中执行的requestChange请求执行handleChange
        */
        var WithoutMixin = React.createClass({
            getInitialState:function(){
                return {message:'Hello!'};
            },
            handleChange:function(newValue){
                this.setState({message:newValue});
            },
            render:function(){
                /*valuelink
                * 它实际上实现的是状态的绑定和change事件的修改
                * requestChange方法接收值来实现state的修改
                */
                var valueLink = {
                    value:this.state.message,
                    requestChange:this.handleChange
                };
                return (
                    <div>
                        <h1>{this.state.message}</h1>
                        <input type="text" valueLink={valueLink} />
                    </div>
                )
            }
        });
        ReactDOM.render(<WithoutMixin/>,document.getElementById('demo'));
    </script>

Demo8

    <div ></div>
    <script type="text/babel">
        /*双向数据流*/
        /*
            valueLink和checkedLink可以一直往子级传递
            子级传递给子级的传递方式是
            <父级套用子级 定义的属性名messageLink={this.linkState(state的Key)}/>
            子级是
            <ChildChildTag messageLink={this.props.messageLink} />
            子子级是
            <input type="text" valueLink={this.props.messageLink}/>
        */
        var TwodTataFlow = React.createClass({
            mixins:[React.addons.LinkedStateMixin],
            getInitialState:function(){
                return {
                    messages:'react is very good',
                    isReactBool:true
                }
            },
            render:function(){
                return (
                    <div>
                        <h1>ME说:{this.state.messages}</h1>
                        <h2>React is very good?{this.state.isReactBool?' yes':' no'}</h2>
                        <input type='text' valueLink={this.linkState('messages')}/><br/><br/>
                        你的选择是:{this.state.isReactBool?' yes':' no'}   <input type='checkbox' checkedLink={this.linkState('isReactBool')}/>
                        <br/><br/><br/>
                        <ChildTag messageLink={this.linkState('messages')} checkLink={this.linkState('isReactBool')}/>
                    </div>
                );
            }
        });
        var ChildTag = React.createClass({
            render:function(){
                return (
                    <div>
                        <h3>这个是子组件</h3>
                        {/*
                            子级继续向下传递props时就需要以下方法,但有时候向下传递时是重复动作,因此props传递时可以{...this.props}
                            <ChildChildTag messageLink={this.props.messageLink} checkLink={this.props.checkLink}/>
                            {...this.props}类似于将对应的valueLink和checkedLink方法传递
                        */}
                        <ChildChildTag {...this.props}/>
                    </div>
                )
            }
        });

        var ChildChildTag = React.createClass({
            render:function(){
                return (
                    <div>
                        <p>你想对我说什么?</p>
                        <input type="text" valueLink={this.props.messageLink}/><br/><br/>
                        <p>React是最好的语言</p>
                        <input type="checkbox" checkedLink={this.props.checkLink}/>
                    </div>
                )
            }
        });
        ReactDOM.render(<TwodTataFlow/>,document.getElementById('demo'));
    </script>

Demo9

    <div ></div>
    <script type="text/babel">
        var Message = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            getInitialState:function(){
                /*
                    在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
                */
                console.log('getInitialState');
                return {titleMsg:'你好 React!',subMsg:'React是世界上最好的语言!',count:0};
            },
            getDefaultProps:function(){
                /*
                    在组件类创建的时候调用一次,然后返回值被缓存下来。
                    如果父组件没有指定 props 中的某个键,则此处返回的对象中的
                    相应属性将会合并到 this.props (使用 in 检测属性)。
                */
                console.log('getDefaultProps');
            },
            componentWillMount:function(){
                /*
                    服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。
                    如果在这个方法内调用 setState,render() 将会感知到更新后的 state,
                    将会执行仅一次,尽管 state 改变了。
                */
                console.log('componentWillMount');
                /*这是在渲染之前的setState*/
                // this.setState({titleMsg:'Hello React!'});
                /*初始化之前设置一个定时器*/
                var self = this;
                this.timer = setInterval(function(){
                    self.setState({count:self.state.count + 1});
                },1000);
            },
            componentDidMount:function(){
                /*
                    在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。
                    在生命周期中的这个时间点,组件拥有一个 DOM 展现,
                    你可以通过 this.getDOMNode() 来获取相应 DOM 节点。
                */
                console.log('componentDidMount');
            },
            componentWillUnmount:function(){
                console.log('组件被你删掉了!');
                /*组件删除之后必须要停止对应的事件*/
                clearInterval(this.timer);
            },
            unmountFunc:function(){
                /*ReactDOM.unmountComponentAtNode(Dom element)删除节点操作*/
                ReactDOM.unmountComponentAtNode(document.getElementById('demo'));
            },
            render:function(){
                if(this.state.count < 2){
                    console.log('渲染结束');
                }
                return (
                    <div>
                        <h1>{this.state.titleMsg}</h1>
                        <h2>计时器:{this.state.count}</h2>
                        <SubMessage {...this.state}/>
                        <button onClick={this.unmountFunc}>点击卸载整个组件</button>
                    </div>);
            }
        });
        var SubMessage = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            render:function(){
                return (
                    <div>
                        <h3>{this.props.subMsg}</h3>
                    </div>);
            }
        });
        ReactDOM.render(<Message/>,document.getElementById('demo'));
    </script>

Demo10

    <div ></div>
    <script type="text/babel">
        var Message = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            getInitialState:function(){
                /*
                    在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
                */
                // console.log('getInitialState');
                return {titleMsg:'你好 React!',subMsg:'React是世界上最好的语言!',count:0};
            },
            getDefaultProps:function(){
            },
            /*componentWillMount:function(){
            },
            componentDidMount:function(){
            },
            componentWillUnmount:function(){
            },*/
            shouldComponentUpdate:function(nextProp,nextState){
                // console.log('shouldComponentUpdate');
                // 假如下次更新时数值大于3时返回false,不让更新                
                if(nextState.count > 10) return false;
                return true;
            },
            componentWillUpdate:function(nextProp,nextState){
                // console.log('componentWillUpdate');
            },
            componentDidUpdate:function(){
                // console.log('componentDidUpdate');
            },
            unmountFunc:function(){
                /*ReactDOM.unmountComponentAtNode(Dom element)删除节点操作*/
                ReactDOM.unmountComponentAtNode(document.getElementById('demo'));
            },
            doUpdate:function(){
                this.setState({count:this.state.count + 1});
            },
            render:function(){
                return (
                    <div>
                        <h1>{this.state.titleMsg}</h1>
                        <h2>计时器:{this.state.count}</h2>
                        <SubMessage {...this.state}/>
                        <button onClick={this.doUpdate}>点一次+一次</button>
                        {/*<button onClick={this.unmountFunc}>点击卸载整个组件</button>*/}
                    </div>);
            }
        });
        var SubMessage = React.createClass({
            /*
                作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props
                组件之中的this.state可以调用了,
            */
            /*
                在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。
                用此函数可以作为 react 在 prop 传入之后, render() 渲染之前更新 state 的机会。
                老的 props 可以通过 this.props 获取到。
                在该函数中调用 this.setState() 将不会引起第二次渲染。
            */
            componentWillReceiveProps:function(nextProp){
                // console.log('子组件将要获取prop');
            },
            shouldComponentUpdate:function(nextProp,nextState){
                /*子组件在被更新时控制其更新方式*/
                if(nextProp.count > 5) return false;
                return true;
            },
            render:function(){
                return (
                    <div>
                        <h3>{this.props.count}</h3>
                    </div>);
            }
        });
        ReactDOM.render(<Message/>,document.getElementById('demo'));
    </script>