react基础使用

本文将对react基础进行由浅到深的讲解.

html模板

    每个react中需要引用的文件
    <script src="../build/react.development.js"></script>
    <script src="../build/react-dom.development.js"></script>
    <script src="../build/babel.min.js"></script>
    // react.js 是 React 的核心库
    // react-dom.js 是提供与 DOM 相关的功能
    // Browser.js 的作用是将 JSX 语法转为 JavaScript 语法


    <div id="example"></div>
    <script type="text/babel">

       //ReactDOM.render 是 React 的最基本方法
       //用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );

JSX 的基本语法规则

      var names = ["Alice", "Emily", "Kate"];
      // JSX 的基本语法规则:
      //遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;
      //遇到代码块(以 { 开头),就用 JavaScript 规则解析。
      ReactDOM.render(
        <div>
          {names.map(function (name, index) {
            return <div key={index}>Hello, {name}!</div>;
          })}
        </div>,
        document.getElementById("example")
      );

style样式写法

 <div style={{ opacity: this.state.opacity }}>
   因为 React 组件样式是一个对象,
   所以第一重大括号表示这是 JavaScript 语法,
   第二重大括号表示样式对象。

运算符

       //true && expression 总是会返回 expression,
      //而 false && expression 总是会返回 false。

      function Mailbox(props) {
        const unreadMessages = props.unreadMessages;
        return (
          <div>
            <h1>Hello!</h1>
            {unreadMessages.length > 0 && (
              <h2>You have {unreadMessages.length} unread messages.</h2>
            )}
          </div>
        );
      }

      const messages = ["React", "Re: React", "Re:Re: React"];
      ReactDOM.render(
        <Mailbox unreadMessages={messages} />,
        document.getElementById("root")
      );
 

组件

  <div id="example"></div>
    <script type="text/babel">
    //将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。
    //所有组件类都必须有自己的 render 方法,用于输出组件。
      class HelloMessage extends React.Component {
        render() {
          return <h1>Hello {this.props.name}</h1>;
        }
      }
     
      // <HelloMessage name="John"> ,
      // 就是 HelloMessage 组件加入一个 name 属性,值为 John。组件的属性可以在组件类的 this.props 对象上获取,
      // 比如 name 属性就可以通过 this.props.name 读取。
      ReactDOM.render(
        <HelloMessage name="John" />,
        document.getElementById('example')
      );


      //注意:class 属性需要写成 className ,for 属性需要写成 htmlFor
    </script>

组件类型

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

       class Welcome extends React.Component {
         render() {
          return <h1>Hello, {this.props.name}</h1>;
         }
      }



      //自定义组件
      //组件名称必须以大写字母开头。
       function Welcome(props) {
         return <h1>Hello, {props.name}</h1>;
       }
       const element = <Welcome name="Sara" />;
       ReactDOM.render(element, document.getElementById("app"));

      //当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)
      //以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。


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

       function App() {
        return (
           <div>
            <Welcome name="Sara" />
             <Welcome name="Cahal" />
             <Welcome name="Edite" />
           </div> //运行三行
         );
       }

       ReactDOM.render(<App />, document.getElementById("app"));

组件传值传参

  //组件可以选择把它的 state 作为 props 向下传递到它的子组件中
  //自定义组件也可以

  <FormattedDate date={this.state.date} />
  function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>,document.getElementById('root');
}



传递参数  id 是你要删除那一行的 ID
//分别通过箭头函数和 Function.prototype.bind 来实现
 <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
 <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

//React 的事件对象 e 会被作为第二个参数传递。
//如果通过箭头函数的方式,事件对象必须显式的进行传递,
//而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

this.state

     //this.props 表示那些一旦定义,就不再改变的特性
    //this.state 是会随着用户互动而产生变化的特性。
      class LikeButton extends React.Component {
        constructor(props) {
          super(props)
          this.state = {
            liked: true
          }
          this.handleClick = this.handleClick.bind(this) 
          // 为了在回调中使用 `this`,这个绑定是必不可少的
          //下面会讲详细事件处理的this
        }
        handleClick(event) {
          this.setState({ liked: !this.state.liked });
          //通过 this.state 属性读取。当用户点击组件,导致状态变化
          //this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法
          //再次渲染组件。
        }
        render() {
          var text = this.state.liked ? 'like' : 'haven\'t liked';
          return (
            <p onClick={this.handleClick}>
              You {text} this. Click to toggle.
            </p>
          );
        }
      }

      ReactDOM.render(
        <LikeButton />,
        document.getElementById('example')
      );

事件处理this

<div id="root"></div>
    <script type="text/babel">
      //添加按钮事件
       <button onClick={activateLasers}>Activate Lasers</button>;

      //在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。
      //你必须显式的使用 preventDefault

      //阻止链接默认打开一个新页面
      function ActionLink() {
        function handleClick(e) {
          e.preventDefault();
          console.log("The link was clicked.");
        }

        return (
          <a href="#" onClick={handleClick}>
            Click me
          </a>
        );
      }

      class Toggle extends React.Component {
        constructor(props) {
          super(props);
          this.state = { isToggleOn: true };

          // 为了在回调中使用 `this`,这个绑定是必不可少的
          this.handleClick = this.handleClick.bind(this);
        }

        // 谨慎对待JSX回调函数中的this,在 JavaScript 中,class 的方法默认不会绑定this。
        // 如果忘记绑定this.handleClick,并把它传入了 onClick,当你调用这个函数的时候this的值为undefined。

        //还有另外两种解决方案
        //1.使用 class fields 正确的绑定回调函数

         class LoggingButton extends React.Component {
        // 此语法确保 `handleClick` 内的 `this` 已被绑定。
        // 注意: 这是 *实验性* 语法。
        handleClick = () => {
          console.log("this is:", this);
        };


        //2.没有使用 class fields 语法,你可以在回调中使用箭头函数 不建议使用
                class LoggingButton extends React.Component {
          handleClick() {
            console.log('this is:', this);
          }

          render() {
            // 此语法确保 `handleClick` 内的 `this` 已被绑定。
            return (
              <button onClick={() => this.handleClick()}>
                Click me
              </button>
            );
          }
        }

        handleClick() {
          this.setState((state) => ({
            isToggleOn: !state.isToggleOn,
          }));
        }

        render() {
          return (
            <button onClick={this.handleClick}>
              {this.state.isToggleOn ? "ON" : "OFF"}
            </button>
          );
        }
      }

      ReactDOM.render(<Toggle />, document.getElementById("root"));

 

PropTypes验证/defaultProps默认值

     var data ;
   //组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求

   //Mytitle组件有一个title属性。
   //PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。
      class MyTitle extends React.Component {
        static propTypes = {
          title: PropTypes.string.isRequired,
        }

    //设置组件默认值 组件内部写法 defaultProps
    //     static defaultProps = {
    //     title:"a"
    // }
        render() {
          return <h1> {this.props.title} </h1>;
        }
      }

    //设置组件默认值 组件外部写法 defaultProps,验证同理
      MyTitle.defaultProps={
        title:"aaaa"
      }

      ReactDOM.render(
        <MyTitle title={data} />,
        document.getElementById('example')
      );

 

表单

 //用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props
      class Input 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} />
              <p>{value}</p>
            </div> );}}  
      // 定义一个 onChange 事件的回调函数,
      // 通过 event.target.value 读取用户输入的值。
      // textarea 元素、select元素、radio元素都属于这种情况
      ReactDOM.render(<Input/>,  document.getElementById('example'));

 

列表

    <div id="root"></div>
    <script type="text/babel">
      //通过使用 {} 在 JSX 内构建一个元素集合。
       const numbers = [1, 2, 3, 4, 5];
       const listItems = numbers.map((number) => <li>{number}</li>);
       ReactDOM.render(<ul>{listItems}</ul>, document.getElementById("root"));

      //列表组件
      key 帮助 React 识别哪些元素改变了,比如被添加或删除。
      一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串
      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("root")
      );

      //用 key 提取组件
      //一个好的经验法则是:在 map() 方法中的元素需要设置 key 属性。

      // 元素的 key 只有放在就近的数组上下文中才有意义。
      // 比方说,如果你提取出一个 ListItem 组件,
      // 你应该把 key 保留在数组中的这个 <ListItem /> 元素上,
      // 而不是放在 ListItem 组件中的 <li> 元素上。

      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("root")
      );

 

列表小练习

class List extends React.Component{      
     render(){
       const numbers=[1,2,3,4,5];
       const listItems = numbers.map((numbers) =>
      <li key='index'>{numbers}</li>
);
       return(
         <div>
          <h1>框架</h1>
          <ul>{listItems}</ul>,
          </div>
       )
     }
   }
   ReactDOM.render(
    <List/>,
        document.getElementById("root")
      );

生命周期

// Mounting:已插入真实 DOM
      // Updating:正在被重新渲染
      // Unmounting:已移出真实 DOM

      //will 函数在进入状态之前调用,did 函数在进入状态之后调用
      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 -= 0.05;
              if (opacity < 0.1) {
                opacity = 1.0;
              }
              this.setState({
                opacity: opacity,
              });
            }.bind(this),
            100 ); 
}
        render() {
          return (
            //因为 React 组件样式是一个对象,
            // 所以第一重大括号表示这是 JavaScript 语法,
            // 第二重大括号表示样式对象。
            <div style={{ opacity: this.state.opacity }}>
              Hello {this.props.name}
            </div>  ); 
 } 
}
      ReactDOM.render(
        <Hello name="world" />,
        document.getElementById("example")
      );

生命周期时间小例子

class Clock extends React.Component {
        constructor(props) {
          super(props);
          this.state = { date: new Date() };
        } //初始化

        // 当 Clock 组件第一次被渲染到 DOM 中的时候,就为其设置一个计时器。“挂载(mount)”。
        // 当 DOM 中 Clock 组件被删除的时候,应该清除计时器。“卸载(unmount)”。

        //componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行
        componentDidMount() {
          this.timerID = setInterval(() => this.tick(), 1000);
        } //3

        // componentWillUnmount() 生命周期方法中清除计时器
        componentWillUnmount() {
          clearInterval(this.timerID);
        } //5

        // 使用tick() 的方法,Clock 组件每秒都会调用它。
        // 使用 this.setState() 来时刻更新组件 state
        tick() {
          this.setState({
            date: new Date(),
          });
        } //4

        render() {
          return (
            <div>
              <h1>Hello, world!</h1>
              <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
            </div>
          );
        }
      } //2

      ReactDOM.render(<Clock />, document.getElementById("root")); //1

获取真实DOM节点

1.字符串
通过 this.refs.a 来引用真实dom的节点---dom 节点上使用
<input  type ="text" ref="a"/> 

2.回调函数
回调函数就是在dom节点或组件上挂载函数,函数的入参是dom节点或组件实例,达到的效果与字符串形式是一样的,都是获取其引用。
<input type="text" ref={(input)=>{this.textInput=input}} 
//可以通过 this.textinput 获取到这个 DOM 元素
 var name = this.textInput.value
 
3.React.createRef()
在React 16.3版本后,使用此方法来创建ref。将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性将能拿到dom节点或组件的实例

)1.通过render放入一个元素
<input  type="text" ref={this.myRef} /> 
    
)2.通过React.createRef()创建Refs并通过ref属性联系到React组件
this.myRef = React.createRef();

)3.通过ref的current属性得到
this.myRef.current.value;

 <input type="text" ref={(input)=>{this.textInput=input}} />
 this.textInput.value

this.props.children

      // this.props.children 属性。它表示组件的所有子节点

      //this.props.children 的值有三种可能:
      //如果当前组件没有子节点,它就是 undefined ;
      //如果有一个子节点,数据类型是 object ;
      //如果有多个子节点,数据类型就是 array
      class NotesList extends React.Component {
        render() {
          return (
            <ol>
              {React.Children.map(this.props.children, function (child) {
                return <li>{child}</li>;
              })}
            </ol>
          );
        }
      }
      //React 提供一个工具方法 React.Children 来处理 this.props.children 。
      //我们可以用 React.Children.map 来遍历子节点,
      //而不用担心 this.props.children 的数据类型是 undefined 还是 object
      ReactDOM.render(
        <NotesList>
          <span>hello</span>
          <span>world</span>
        </NotesList>,
        document.getElementById("example")
      );

Ajax

<div id="example"></div>
    <script type="text/babel">
    //使用 componentDidMount 方法设置 Ajax 请求
    //等到请求成功,再用 this.setState 方法重新渲染 UI 
      class UserGist extends React.Component {
        constructor(props) {
          super(props)
          this.state = {
            username: '',
            lastGistUrl: ''
          }
        }
       //$.get() 方法使用 HTTP GET 请求从服务器加载数据。
       //$.get(URL,data,function(data,status,xhr),dataType) 
        //function(data,status,xhr) 可选。规定当请求成功时运行的函数。
        //dataType   可选。规定预期的服务器响应的数据类型。
        componentDidMount() {
          $.get(this.props.source, function(result) {
            var lastGist = result[0];
            this.setState({
              username: lastGist.owner.login,
              lastGistUrl: lastGist.html_url
            });
          }.bind(this));
        }

        render() {
          return (
            <div>
              {this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>.
            </div>
          );
        }
      }

      ReactDOM.render(
        <UserGist source="https://api.github.com/users/octocat/gists" />,
        document.getElementById('example')
      );

promise

class RepoList extends React.Component {
        constructor(props) {
          super(props)
          this.state = {
            loading: true,
            error: null,
            data: null
          };
        }

        componentDidMount() {
          this.props.promise.then(
            value => this.setState({loading: false, data: value}),
            error => this.setState({loading: false, error: error}));
        }

        render() {
          if (this.state.loading) {
            return <span>Loading...</span>;
          }
          else if (this.state.error !== null) {
            return <span>Error: {this.state.error.message}</span>;
          }
          else {
            var repos = this.state.data.items;
            var repoList = repos.map(function (repo, index) {
              return (
                <li key={index}><a href={repo.html_url}>{repo.name}</a> ({repo.stargazers_count} stars) <br/> {repo.description}</li>
              );
            });
            return (
              <main>
                <h1>Most Popular JavaScript Projects in Github</h1>
                <ol>{repoList}</ol>
              </main>
            );
          }
        }
      }

      ReactDOM.render(
        <RepoList promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} />,
        document.getElementById('example')
      );

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值