react官网学习笔记

学习地址:https://react.docschina.org/

http://www.runoob.com/react/react-tutorial.html

1.react第一个实例:Hello, world!

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<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="example"></div>
<script type="text/babel">
ReactDOM.render(
	<h1>Hello, world!</h1>,
	document.getElementById('example')
);
</script>

</body>
</html>

2.React 安装

本教程使用了 React 的版本为 16.4.0,你可以在官网 https://reactjs.org/ 下载最新版。

你也可以直接使用 Staticfile CDN 的 React CDN 库,地址如下:

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

官方提供的 CDN 地址:

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>

将这三个地址写到<head></head>标签内

3.元素渲染

    <!-- 我们用react开发应用时一般只会定义一个根节点,此处定义一个id为example的div -->
    <div id="example"></div>
    <script type="text/babel">
        //元素式构成React应用的最小单位,用于描述屏幕上输出的内容
        const element = <h1>Hello, world!</h1>;
        //要将React元素渲染到根节点中,用ReactDOM.render()方法
        ReactDOM.render(
            element,
            document.getElementById('example')
        );
    </script>

4.更新元素渲染

    <div id="example"></div>
    <script type="text/babel">
        //更新元素渲染:React元素都是不可变的。当元素被创建之后,无法改变内容或属性。只能创建一个新的元素
        // toLocaleTimeString() 方法返回该日期对象时间部分的字符串
        function tick(){
            const element = (
                <div>
                    <h1>Hello, world!</h1>
                    <h2>现在是{new Date().toLocaleTimeString()}.</h2>
                </div>
            );
            ReactDOM.render(
                element,
                document.getElementById('example')
            );
        }
        setInterval(tick,1000);//通过 setInterval() 方法,每秒钟调用一次 ReactDOM.render()。

5.将要展示的部分封装起来

扫描二维码关注公众号,回复: 4288795 查看本文章
        function Clock(props){
            return(
                <div>
                    <h1>封装起来</h1>
                    <h2>现在是{props.date.toLocaleTimeString()}.</h2>
                </div>
            );
        }
        function tick(){
            ReactDOM.render(
                <Clock date={new Date()}/>,
                document.getElementById("example")
            );
        }
        setInterval(tick,1000);

6.创建React.Component的类,需要注意的是在 render() 方法中,需要使用 this.props 替换 props:

        class Clock extends React.Component{
            render(){
                return(
                    <div>
                        <h1>创建一个类</h1>
                        <h2>现在是{this.props.date.toLocaleTimeString()}.</h2>
                    </div>
                );
            }
        }
        function tick(){
            ReactDOM.render(
                <Clock date = {new Date()} />,
                document.getElementById("example")
            );
        }
        setInterval(tick,1000);

7.React JSX

React使用JSX来替代常规的javascript

实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。

    <div id="example"></div>
    <script type="text/babel">
        ReactDOM.render(
            <div>
                <h1>React JSX</h1>
                <p data-myattribute="somevalue">实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。</p>
            </div>
            ,
            document.getElementById("example")
        );
    </script>

8.React JSX 代码可以放在一个独立文件上,例如我们创建一个 helloworld_react.js 文件

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
<body>
  <div id="example"></div>
  <script type="text/babel" src="./helloworld_react.js"></script>
</body>

9.JSX中使用javascript表达式,表达式写在{}中

在JSX中不能使用if else语句,但可以使用conditional(三元运算)表达式来替代

    <script type="text/babel">
        var i=1;
        ReactDOM.render(
            <div>
                <h1>{i==1?"True!":"False"}</h1>
            </div>
            ,
            document.getElementById("example")
        )
    </script>

10.样式

        var myStyle={
            fontSize:100,
            color:"#FF0000"
        };
        ReactDOM.render(
            <h1 style = {myStyle}>样式</h1>,
            document.getElementById("example")
        )

11.注释

注释需要写在一对花括号中

        ReactDOM.render(
            <div>
                <h1>注释</h1>
                {/* 注释需要写在一对花括号中 */}
            </div>,
            document.getElementById("example")
        )

12.数组

JSX允许再模板中插入数组,数组会自动展开所有成员:

        var arr = [1,2];
        ReactDOM.render(
            <div>{arr}</div>,
            document.getElementById("example")
        );

13.HTML标签vs.React组件

要渲染HTML标签,只需在JSX里使用小写字母的标签名:

    <script type="text/babel">
        var myDivElement = <div className="foo" />;
        ReactDOM.render(myDivElement,document.getElementById("example"));
    </script>

14.React组件

    <script type="text/babel">
        function HelloMessage(props){
            return <h1>组件</h1>;
        }
        const element = <HelloMessage />;
        ReactDOM.render(element,document.getElementById("example"));
    </script>

向组件传值

        function HelloMessage(props){
            return <h1>组件{props.name}!</h1>;
        }
        const element = <HelloMessage name="Alisa" />;
        ReactDOM.render(element,document.getElementById("example"));

复合组件

    <script type="text/babel">
        function Name(props){
            return <h1>姓名:{props.name}</h1>;
        }
        function Sex(props){
            return <h1>性别:{props.sex}</h1>;
        }
        function Age(props){
            return <h1>年龄:{props.age}</h1>;
        }
        function Study(){
            return(
                <div>
                    <Name name="Alisa" />
                    <Sex sex="女" />
                    <Age age="23" />
                </div>
            )
        }
        ReactDOM.render(
            <Study />,
            document.getElementById("example")
        )
    </script>

15.React State(状态)

创建一个名称扩展为React.Component的ES6类,在render()方法中使用this.state来修改当前的时间

添加一个类构造函数来初始化状态this.state,类组件应始终使用props调用基础构造函数

    <script type="text/babel">
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            render(){
                return(
                    <div>
                        <h1>在render()方法中使用this.state来修改当前的时间</h1>
                        <h2>现在是{this.state.date.toLocaleTimeString()}.</h2>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

16.将生命周期方法添加到类中

componentDidMount() 与 componentWillUnmount() 方法被称作生命周期钩子。

在组件输出到 DOM 后会执行 componentDidMount() 钩子,我们就可以在这个钩子上设置一个定时器。

this.timerID 为计算器的 ID,我们可以在 componentWillUnmount() 钩子中卸载计算器。

    <script type="text/babel">
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID = setInterval(
                    ()=> this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return (
                    <div>
                        <h1>生成/移除定时器</h1>
                        <h2>现在是{this.state.date.toLocaleTimeString()}.</h2>
                    </div>
                );
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

17.数据自顶向下流动

    <script type="text/babel">
        function FormattedDate(props){
            return <h2>现在是{props.date.toLocaleTimeString()}.</h2>
        }
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID=setInterval(
                    ()=>this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return(
                    <div>
                        <h1>实例中 FormattedDate 组件将在其属性中接收到 date 值,并且不知道它是来自 Clock 状态、还是来自 Clock 的属性、亦或手工输入</h1>
                        <FormattedDate date={this.state.date} />
                    </div>
                );
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

所有组件都是真正隔离的

    <script type="text/babel">
        function FormattedDate(props){
            return <h2>现在是{props.date.toLocaleTimeString()}.</h2>;
        }
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID=setInterval(
                    ()=>this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return (
                    <div>
                        <h1>为了表明所有组件都是真正隔离的,我们可以创建一个 App 组件,它渲染三个Clock:</h1>
                        <FormattedDate date={this.state.date} />
                    </div>
                );
            }
        }
        function App(){
            return(
                <div>
                    <Clock />
                    <Clock />
                    <Clock />
                </div>
            )
        }
        ReactDOM.render(
            <App />,
            document.getElementById("example")
        )
    </script>

18.Props

使用props

    <script type="text/babel">
        function HelloMessage(props){
            return <h1>Hello{props.name}!</h1>
        }
        const element = <HelloMessage name="Alisa" />;
        ReactDOM.render(
            element,document.getElementById("example")
        );
    </script>

默认props

    <script type="text/babel">
        class HelloMessage extends React.Component{
            render(){
                return (
                    <h1>Hello,{this.props.name}</h1>
                );
            }
        }
        HelloMessage.defaultProps = {
            name:"Alisa"
        };
        const element = <HelloMessage />;
        ReactDOM.render(
            element,document.getElementById("example")
        );
    </script>

state和Props

我们可以在父组件中设置state,并通过在子组件上使用props将其传递到子组件上

    <script type="text/babel">
    class Website extends React.Component{
        constructor(){
            super();
            this.state={
                name:"Alisa",
                sex:"女"
            }
        }
        render(){
            return (
                <div>
                    <Name name={this.state.name} />
                    <Sex sex={this.state.sex} />
                </div>
            )
        }
    }
    class Name extends React.Component{
        render(){
            return (
                <h1>{this.props.name}</h1>
            );
        }
    }
    class Sex extends React.Component{
        render(){
            return(
                <a href={this.props.sex}>{this.props.sex}</a>
            );
        }
    }
    ReactDOM.render(
        <Website />,document.getElementById("example")
    );
    </script>

19.Props验证

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
    <!-- Props验证必须要下面这个js链接 -->
    <script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- Props -->
    <!-- Props验证 -->
    <script type="text/babel">
        var title="Alisa";//如果此处var title=123,控制器那里会报错,显示数据类型错误
        class MyTitle extends React.Component{
            render(){
                return (
                    <h1>Hello ,{this.props.title}</h1>
                );
            }
        }
        MyTitle.propTypes={
            title:PropTypes.string
        };
        ReactDOM.render(
            <MyTitle title={title} />,document.getElementById("example")
        )
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.staticfile.org/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.staticfile.org/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- Props -->
    <!-- Props验证 -->
    <!-- Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。 -->
    <!-- 创建一个 Mytitle 组件,属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 : -->
    <script type="text/babel">
        var title="Alisa";//如果此处var title=123,控制器那里会报错,显示数据类型错误
        var MyTitle = React.createClass({
            propTypes:{
                title:React.PropTypes.string.isRequired,
            },
            render:function(){
                return <h1>{this.props.title}</h1>;
            }
        });
        ReactDOM.render(
            <MyTitle title={title} />,
            document.getElementById("example")
        );
    </script>
</body>
</html>

更多验证器说明:

        MyComponent.propTypes = {
            //可以声明prop为指定的js基本数据类型,默认情况,这些数据是可选的
            optionalArray:React.PropTypes.array,
            optionalBool:React.PropTypes.bool,
            optionalFunc:React.PropTypes.func,
            optionalNumber:React.PropTypes.number,
            optionalObject:React.PropTypes.object,
            optionalString:React.PropTypes.string,
            // 可以被渲染的对象 numbers, strings, elements 或 array
            optionalNode:React.PropTypes.node,
            //React元素
            optionalElement:React.PropTypes.element,
            //用JS的instanceof操作符声明prop为类的实例
            optionalMessage:React.PropTypes.instanceOf(Message),
            //用enum来限制prop只接收指定的值。
            optionalEnum:React.PropTypes.oneOf(["News","Photos"]),
            //可以是多个对象类型中的一个
            optionalUnion:React.PropTypes.oneOfType([
                React.PropTypes.string,
                React.PropTypes.number,
                React.PropTypes.instanceOf(Message)
            ]),
            //指定类型组成的数组
            optionalArrayOf:React.PropTypes.arrayOf(React.PropTypes.number),
            //指定类型的属性构成的对象
            optionalObjectOf:React.PropTypes.objectOf(React.PropTypes.number),
            //特定shape参数的对象
            optionalObjectWithShape:React.PropTypes.shape({
                color:React.PropTypes.string,
                fontSize:React.PropTypes.number
            }),
            //任意类型加上"isRequired"来使prop不可空
            requiredFunc:React.PropTypes.func.isRequired,
            //不可空的任意类型
            requiredAny:React.PropTypes.any.isRequired,
            //自定义验证器。如果验证失败需要返回一个Error对象。不要直接使用"console.warn"或抛异常,因为这样"oneOfType"会失效。
            customProp:function(props,propName,componentName){
                if(!/matchme/.test(props[propName])){
                    return new Error("Validationfailed!");
                }
            }
        }

20.React 事件处理

React 元素的事件处理和 DOM 元素类似。但是有一点语法上的不同:

React 事件绑定属性的命名采用驼峰式写法,而不是小写。

如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)

        class Toggle extends React.Component{
            constructor(props){
                super(props);
                this.state={isToggleOn:true};
                //这边绑定是必要的,这样'this'才能在回调函数中使用
                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("example")
        );

使用属性初始化器来正确的绑定回调函数:

    <script type="text/babel">
        class LoggingButton extends React.Component{
            //这个语法确保了"this"绑定在handleClick
            handClick=()=>{
                console.log("this is:",this);
            }
            render(){
                return (
                    <button onClick={this.handClick}>Click me</button>
                )
            }
        }
        ReactDOM.render(
            <LoggingButton />,
            document.getElementById("example")
        );
    </script>

在回调函数中使用 箭头函数:

    <script type="text/babel">
        class LoggingButton extends React.Component{
            handleClick(){
                console.log("this is:",this);
            }
            render(){
                //这个语法确保了'this'绑定在handleClick中
                return(
                    <button onClick={(e)=>this.handleClick(e)}>Click me</button>
                )
            }
        }
        ReactDOM.render(
            <LoggingButton />,
            document.getElementById("example")
        );
    </script>

21.向事件处理程序传递参数

若是 id 是你要删除那一行的 id,以下两种方式都可以向事件处理程序传递参数:

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

通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面

    <script type="text/babel">
        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>
                    {/* 通过bind()方法传递参数。 */}
                    <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Popper />,
            document.getElementById("example")
        );
    </script>

22.React 条件渲染

    <script type="text/babel">
        function UserGreeting(props){
            return <h1>欢迎回来!</h1>;
        }
        function GuestGreeting(props){
            return <h1>请先注册!</h1>;
        }
        function Greeting(props){
            const isLoggedIn = props.isLoggedIn;
            if(isLoggedIn){
                return <UserGreeting />
            }
            return <GuestGreeting />
        }
        ReactDOM.render(
            //尝试修改isLoggedIn={true}
            <Greeting isLoggedIn={false} />,
            document.getElementById("example")
        );
    </script>

23.元素变量

    <script type="text/babel">
        function LoginButton(props){
            return (
                <button onClick={props.onClick}>登录</button>
            );
        }
        function LogoutButton(props){
            return (
                <button onClick={props.onClick}>退出</button>
            )
        }
        function UserGreeting(props){
            return <h1>欢迎回来!</h1>;
        }
        function GuestGreeting(props){
            return <h1>请先注册!</h1>;
        }
        function Greeting(props){
            const isLoggedIn=props.isLoggedIn;
            if(isLoggedIn){
                return <UserGreeting />;
            }
            return <GuestGreeting />;
        }
        class LoginControl extends React.Component{
            constructor(props){
                super(props);
                this.handleLoginClick= this.handleLoginClick.bind(this);
                this.handleLogoutClick=this.handleLogoutClick.bind(this);
                this.state={isLoggedIn:false};
            }
            handleLoginClick(){
                this.setState({isLoggedIn:true});
            }
            handleLogoutClick(){
                this.setState({isLoggedIn:false});
            }
            render(){
                const isLoggedIn=this.state.isLoggedIn;
                let button = null;
                if(isLoggedIn){
                    button=<LogoutButton onClick={this.handleLogoutClick} />;
                }else{
                    button=<LoginButton onClick={this.handleLoginClick} />;
                }
                return (
                    <div>
                        <Greeting isLoggedIn={isLoggedIn} />
                        {button}
                    </div>
                )
            }
        }
        ReactDOM.render(
            <LoginControls/>,
            document.getElementById("example")
        )
    </script>

24.与运算符&&

    <script type="text/babel">
        function Mailbox(props){
            const unreadMessages = props.unreadMessages;
            return (
                <div>
                    <h1>Hello!</h1>
                    {unreadMessages.length>0 &&
                        <h2>您有{unreadMessages.length}条未读信息。</h2>
                    }
                </div>
            );
        }
        const messages = ["Alisa","Hello","World","Happy"];
        ReactDOM.render(
            <Mailbox unreadMessages={messages} />,
            document.getElementById("example")
        );
    </script>

25.阻止组件渲染

    <script type="text/babel">
        function WarningBanner(props){
            if(!props.warn){
                return null;
            }
            return (
                <div className="warning">警告!</div>
            );
        }
        class Page extends React.Component{
            constructor(props){
                super(props);
                this.state = {showWarning:true}
                this.handleToggleClick = this.handleToggleClick.bind(this);
            }
            handleToggleClick(){
                this.setState(prevState=>({
                    showWarning:!prevState.showWarning
                }));
            }
            render(){
                return (
                    <div>
                        <WarningBanner warn={this.state.showWarning}/>
                        <button onClick={this.handleToggleClick}>
                            {this.state.showWarning ? "隐藏":"显示"}
                        </button>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Page />,
            document.getElementById("example")
        )
    </script>

26.React 列表 & Keys

使用 map() 方法遍历数组生成了一个 1 到 5 的数字列表:

    <script type="text/babel">
        const numbers = [1,2,3,4,5];
        const listItems = numbers.map((numbers)=>
            <li>{numbers}</li>
        );
        ReactDOM.render(
            <ul>{listItems}</ul>,
            document.getElementById("example")
        );
    </script>

27.将以上实例重构成一个组件,组件接收数组参数,每个列表元素分配一个 key

    <script type="text/babel">
        function NumberList(props){
            const numbers = props.numbers;
            const listItems = numbers.map((number)=>
                <li key={number.toString()}>{number}</li>
            );
            return (
                <ul>{listItems}</ul>
            );
        }
        const numbers=[1,2,3,4,5];
        ReactDOM.render(
            <NumberList numbers={numbers} />,
            document.getElementById("example")
        );
    </script>

用key提取组件

    <script type="text/babel">
        function ListItem(props){
            //这里不需要指定Key:
            return <li>{props.value}</li>
        }
        function NumberList(props){
            const numbers = props.numbers;
            const listItems = numbers.map((number)=>
                //key应该在数组的上下文中被指定
                <ListItem key={number.toString()} value={number} />
            );
            return (
                <ul>{listItems}</ul>
            );
        }
        const numbers = [1,2,3,4,5];
        ReactDOM.render(
            <NumberList numbers={numbers} />,
            document.getElementById("example")
        )
    </script>

元素的 key 在他的兄弟元素之间应该唯一

    <script type="text/babel">
        function Blog(props){
            const sidebar = (
                <ul>
                    {props.posts.map((post)=>
                        <li key={post.id}>{post.title}</li>
                    )}
                </ul>
            );
            const content = props.posts.map((post)=>
                <div key={post.id}>
                    <h3>{post.title}</h3>
                    <p>{post.content}</p>
                </div>
            );
            return (
                <div>
                {sidebar}
                <hr/>
                {content}
                </div>
            );
        }
        const posts = [
            {id:1,title:"Hello World",content:"Welcome"},
            {id:2,title:"World!",content:"All"}
        ];
        ReactDOM.render(
            <Blog posts = {posts} />,
            document.getElementById("example")
        )
    </script>

28.React 组件 API

设置状态:setState

setState(object nextState[, function callback])

nextState,将要设置的新状态,该状态会和当前的state合并

callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。

合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。

    <script type="text/babel">
        class Counter extends React.Component{
            constructor(props){
                super(props);
                this.state = {clickCount:0};
                this.handleClick = this.handleClick.bind(this);
            }
            handleClick(){
                this.setState(function(state){
                    return {clickCount:state.clickCount+1};
                });
            }
            render(){
                return (
                    <h2 onClick={this.handleClick}>
                    点我!点击次数为:{this.state.clickCount}
                    </h2>
                );
            }
        }
        ReactDOM.render(
            <Counter />,
            document.getElementById("example")
        );
    </script>

替换状态:replaceState

replaceState(object nextState[, function callback])

nextState,将要设置的新状态,该状态会替换当前的state。

callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。

设置属性:setProps
setProps(object nextProps[, function callback])
nextProps,将要设置的新属性,该状态会和当前的props合并
callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。
设置组件属性,并重新渲染组件。

替换属性:replaceProps
replaceProps(object nextProps[, function callback])
nextProps,将要设置的新属性,该属性会替换当前的props。
callback,可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。
replaceProps()方法与setProps类似,但它会删除原有 props。

强制更新:forceUpdate
forceUpdate([function callback])
参数说明
callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。

forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()

一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。
 

获取DOM节点:findDOMNode
DOMElement findDOMNode()
返回值:DOM元素DOMElement
如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。

判断组件挂载状态:isMounted
bool isMounted()
返回值:true或false,表示组件是否已挂载到DOM中
isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

29.React 组件生命周期

组件的生命周期可分成三个状态:

Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
生命周期的方法有:

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

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

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

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

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

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

componentWillUnmount在组件从 DOM 中移除之前立刻被调用。

    <script type="text/babel">
        class Hello extends React.Component{
            constructor(props){
                super(props);
                this.state = {opacity:1.0};
            }
            componentDidMount(){
                this.timer = setInterval(function(){
                    var opacity = this.state.opacity;
                    opacity -= .05;
                    if(opacity <0.1){
                        opacity=1.0;
                    }
                    this.setState({
                        opacity:opacity
                    });
                }.bind(this),100);
            }
            render(){
                return (
                    <div style={{opacity:this.state.opacity}}>Hello{this.props.name}</div>
                );
            }
        }
        ReactDOM.render(
            <Hello name="world" />,
            document.body
        );
    </script>

以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中。

    <script type="text/babel">
        class Button extends React.Component{
            constructor(props){
                super(props);
                this.state = {data:0};
                this.setNewNumber = this.setNewNumber.bind(this);
            }
            setNewNumber(){
                this.setState({data:this.state.data+1})
            }
            render(){
                return(
                    <div>
                        <button onClick={this.setNewNumber}>INCREMENT</button>
                        <Content myNumber = {this.state.data}></Content>
                    </div>
                );
            }
        }
        class Content extends React.Component{
            componentWillMount(){
                console.log("componentWillMount")
            }
            componentDidMount(){
                console.log("componentDidMount")
            }
            componentWillReceiveProps(newProps){
                console.log("componentWillReceiveProps")
            }
            shouldComponentUpdate(newProps,newState){
                return true;
            }
            componentWillUpdate(nextProps,nextState){
                console.log("componentWillUpdate")
            }
            componentDidUpdate(prevProps,prevState){
                console.log("componentDidUpdate")
            }
            render(){
                return(
                    <div><h3>{this.props.myNumber}</h3></div>
                );
            }
        }
        ReactDOM.render(
            <div><Button /></div>,
            document.getElementById("example")
        )
    </script>

30.React AJAX

<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.staticfile.org/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.22.1/babel.min.js"></script>
    <!-- 必须加下面这个链接,否则报错$没有定义 -->
    <script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- React AJAX -->
    <script type="text/babel">
        class UserGist extends React.Component{
            constructor(props){
                super(props);
                this.state = {username:"",lastGistUrl:""};
            }
            componentDidMount(){
                this.serverRequest = $.get(this.props.source,function(result){
                    var lastGist = result[0];
                    this.setState({
                        username:lastGist.owner.login,
                        lastGistUrl:lastGist.html_url
                    });
                }.bind(this));
            }
            componentWillUnmount(){
                this.serverRequest.abort();
            }
            render(){
                return (
                    <div>
                        {this.state.username}用户最新的Gist共享地址:
                        <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
                    </div>
                );
            }
        }
        ReactDOM.render(
            <UserGist source="https://api.github.com/users/octocat/gists" />,
            document.getElementById("example")
        )
    </script>
</body>
</html>

31.React 表单与事件

设置了输入框 input 值 value = {this.state.data}。在输入框值发生变化时我们可以更新 state。我们可以使用 onChange 事件来监听 input 的变化,并修改 state。 

    <script type="text/babel">
        class HelloMessage extends React.Component{
            constructor(props){
                super(props);
                this.state={value:"Hello!"};
                this.handleChange = this.handleChange.bind(this);
            }
            handleChange(event){
                this.setState({value:event.target.value});
            }
            render(){
                var value = this.state.value;
                return <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <h4>{value}</h4>
                </div>;
            }
        }
        ReactDOM.render(
            <HelloMessage />,
            document.getElementById("example")
        );
    </script>

32.React Refs

允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。

    <script type="text/babel">
        class MyComponent extends React.Component{
            handleClick(){
                //使用原生的DOM API获取焦点
                this.refs.myInput.focus();
            }
            render(){
                //当组件插入到DOM后,ref属性添加一个组件的引用于到this.refs
                return(
                    <div>
                        <input type="text" ref="myInput" />
                        <input type="button" value="点我输入框获取焦点" onClick={this.handleClick.bind(this)} />
                    </div>
                );
            }
        }
        ReactDOM.render(
            <MyComponent />,
            document.getElementById("example")
        )
    </script>

33.接下来是自己的一些小练习

  • 点击弹出文案
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <div className="App">
        <h1 className="abc" onClick={this.handleClick}>Hello, world!</h1>
      </div>
    );
  }
}

export default App;
  • 新建一个Content.js,同时,Content.js里面的值是通过在开头定义好,然后引入的。再将Content.js引入到App.js

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Content from "./Content"

class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <Content />
    );
  }
}

export default App;

Content.js

import React, { Component } from 'react';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
      </div>
    );
  }
}
export default Con;
  • 将App.js内的一个类传递到另外一个类中
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
      </div>
    );
  }
}
class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <Con />
    );
  }
}

export default App;
  • 定义一个组件并传值,可以通过function定义一个函数,也可以通过class定一个类来实现
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
const h1style={
  color:"blue"
}
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1 style={h1style}>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
        <button onClick={Welcome}>click me</button>
      </div>
    );
  }
}
function Welcome(props){
  return(
    console.log(123)
  )
}
class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <div>
        <Con />
        <button onClick={this.handleClick}>click me</button>
      </div>
    );
  }
}

export default App;
  • 先在中端通过npm install prop-types --save下载prop-types,然后输入代码,虽然会显示内容,但是不符合类型的定义类型会在控制台报错
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import PropTypes from 'prop-types';
class Son extends React.Component{
  render(){
    return(
      <div style={{padding:30}}>
        {this.props.number}
        <hr/>
        {this.props.array}
        <hr/>
        {this.props.boolean.toString()}
      </div>
    )
  }
}
Son.propTypes = {
  number:PropTypes.number,
  array:PropTypes.array,
  boolean:PropTypes.bool
}
class Father extends React.Component{
  render(){
    return (
      <Son number = {1} array={"[1,2,3]"} boolean = {"true"}
       />
    )
  }
}
export default Father;

猜你喜欢

转载自blog.csdn.net/qq_37815596/article/details/83379589