react 基礎語法使用

  剛開始不久react,在菜鳥上及其餘前輩網站上學習,下面開始個人自學筆記。html

  包括:react

  • 渲染元素
  • 組件(函數方法定義、es6 class定義)
  • 事件處理
  • 條件渲染
  • 列表

  下面代碼部分將不會再寫html部分,html部分以下:es6

<div id="example"></div>

  多餘的話很少說,具體以下:express

  • 渲染元素(函數方法,es6方式)
    •  函數方法
function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>如今是 {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('example')
  );
}

setInterval(tick, 1000);
    • es6方法
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>如今是 {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
 
function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('example')
  );
}
 
setInterval(tick, 1000);
  • 組件

  一、咱們可使用函數定義一個組件:npm

function HelloMessage(props) {
    return <h1>Hello World!</h1>;
}

  也可使用ES6 class來定義一個組件:數組

class Welcome extends React.Component {
  render() {
    return <h1>Hello World!</h1>;
  }
}

  2.須要向組件傳遞參數,可使用this.props對象babel

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

  注意:在添加屬性時,class屬性須要寫成className,for屬性須要寫成htmlFor,這是由於class和for是JavaScript的保留字。dom

  複合組件ide

  能夠經過建立多個組件來合成一個組件,即把組件的不一樣功能點進行分離。函數

<script type="text/babel">
function Name(props) {
    return <h1>名稱:{props.name}</h1>;
}
function Url(props) {
    return <h1>地址:{props.url}</h1>;
}
function Nickname(props) {
    return <h1>小名:{props.nickname}</h1>;
}
function App() {
    return (
    <div>
        <Name name="Tom" />
        <Url url="https://www.cnblogs.com/freedom-feng/" />
        <Nickname nickname="Jack" />
    </div>
    );
}

ReactDOM.render(
     <App />,
    document.getElementById('example')
);
</script>
  • 事件

  使用 ES6 class 語法來定義一個組件的時候,事件處理器會成爲類的一個方法(推薦方式)。例如,下面的 Toggle 組件渲染一個讓用戶切換開關狀態的按鈕:

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')
);

  注意:類的方法默認是不會綁定 this 的。若是你忘記綁定 this.handleClick 並把它傳入 onClick, 當你調用這個函數的時候 this 的值會是 undefined。

  若是上面使用 bind 讓你很煩,這裏有兩種方式能夠解決。若是你正在使用實驗性的屬性初始化器語法,你可使用屬性初始化器來正確的綁定回調函數:

<script type="text/babel">
class LoggingButton extends React.Component {
  // 這個語法確保了 `this` 綁定在  handleClick 中
  // 這裏只是一個測試
  handleClick = () => {
    console.log('this is:', this);
  }
 
  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
ReactDOM.render(
  <LoggingButton />,
  document.getElementById('example')
);
</script>

  若是你沒有使用屬性初始化器語法,你能夠在回調函數中使用 箭頭函數:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }
 
  render() {
    //  這個語法確保了 `this` 綁定在  handleClick 中
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}
    • 事件傳參
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

  上面兩種方式是等價的。

  在例子中,參數e做爲時間對象將被做爲第二個參數進行傳遞。經過箭頭函數的方式,事件對象必須顯式的進行傳遞,可是經過bind的方式,時間對象以及更多的參數將會被隱式的進行傳遞。

  注意:經過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() 方法傳遞參數。 */}
                <button onClick={this.preventPop.bind(this,this.state.name)}>Click</button>
            </div>
        );
    }
}

ReactDOM.render(
  <Popper />,
  document.getElementById('example')
);
</script>
  • 條件渲染

  先看兩個組件:

function UserGreeting(props) {
  return <h1>歡迎回來!</h1>;
}

function GuestGreeting(props) {
  return <h1>請先註冊。</h1>;
}

  建立一個 Greeting 組件,它會根據用戶是否登陸來顯示其中之一:

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}
 
ReactDOM.render(
  // 嘗試修改 isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById('example')
);

  元素變量

  可使用變量來儲存元素。它能夠幫助你有條件的渲染組件的一部分,而輸出的其餘部分不會更改。

  在下面的例子中,咱們將要建立一個名爲 LoginControl 的有狀態的組件。

  它會根據當前的狀態來渲染 <LoginButton /> 或 <LogoutButton />,它也將渲染前面例子中的 <Greeting />。

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(
  <LoginControl />,
  document.getElementById('example')
);

  與運算符 &&

  用花括號包裹代碼在 JSX 中嵌入任何表達式 ,也包括 JavaScript 的邏輯與 &&,它能夠方便地條件渲染一個元素。

<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 = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('example')
);
</script>  

  在 JavaScript 中,true && expression 老是返回 expression,而 false && expression 老是返回 false

  所以,若是條件是 true&& 右側的元素就會被渲染,若是是 false,React 會忽略並跳過它。

  三目運算符

  條件渲染的另外一種方法是使用 JavaScript 的條件運算符:

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

  阻止組件渲染

  在極少數狀況下,你可能但願隱藏組件,即便它被其餘組件渲染。讓 render 方法返回 null 而不是它的渲染結果便可實現。

  在下面的例子中,<WarningBanner /> 根據屬性 warn 的值條件渲染。若是 warn 的值是 false,則組件不會渲染:

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')
);

  組件的 render 方法返回 null 並不會影響該組件生命週期方法的回調。例如,componentWillUpdate 和 componentDidUpdate 依然能夠被調用。

  • 列表

  使用JavaScript的map()方法來建立列表

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

  能夠將以上實例重構成一個組件,組件接收數組參數,每一個列表元素分配一個 key,否則會出現警告 a key should be provided for list items,意思就是須要包含 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('example')
);

  keys

  Keys 能夠在 DOM 中的某些元素被增長或刪除的時候幫助 React 識別哪些元素髮生了變化。所以你應當給數組中的每個元素賦予一個肯定的標識。

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

  一個元素的 key 最好是這個元素在列表中擁有的一個獨一無二的字符串。一般,咱們使用來自數據的 id 做爲元素的 key:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

  當元素沒有肯定的 id 時,你可使用他的序列號索引 index 做爲 key:

const todoItems = todos.map((todo, index) =>
  // 只有在沒有肯定的 id 時使用
  <li key={index}>
    {todo.text}
  </li>
);

  若是列表能夠從新排序,不建議使用索引來進行排序,由於這會致使渲染變得很慢。

  用key提取組件

  元素的 key 只有在它和它的兄弟節點對比時纔有意義。

  錯誤示範:

function ListItem(props) {
  const value = props.value;
  return (
    // 錯啦!你不須要在這裏指定key:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    //錯啦!元素的key應該在這裏指定:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('example')
);

  key正確使用方式:

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')
);

  在 map() 方法的內部調用元素時,最好隨時記得爲每個元素加上一個獨一無二的 key。

  元素的key在他的兄弟元素之間應該惟一

  數組元素中使用的 key 在其兄弟之間應該是獨一無二的。然而,它們不須要是全局惟一的。當咱們生成兩個不一樣的數組時,咱們可使用相同的鍵。

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 to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('example')
);

  key 會做爲給 React 的提示,但不會傳遞給你的組件。若是您的組件中須要使用和 key 相同的值,請將其做爲屬性傳遞:

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

  上面例子中,Post 組件能夠讀出 props.id,可是不能讀出 props.key。

  在jsx中嵌入map()

  在上面的例子中,咱們聲明瞭一個單獨的 listItems 變量並將其包含在 JSX 中:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

  JSX 容許在大括號中嵌入任何表達式,因此咱們能夠在 map() 中這樣使用:

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
 
      )}
    </ul>
  );
}

  這麼作有時可使你的代碼更清晰,但有時這種風格也會被濫用。就像在 JavaScript 中同樣,什麼時候須要爲了可讀性提取出一個變量,這徹底取決於你。但請記住,若是一個 map() 嵌套了太多層級,那你就能夠提取出組件。

 

 

 

 

 

  以上來自菜鳥教程:https://www.runoob.com/react/react-tutorial.html

相關文章
相關標籤/搜索