1. 程式人生 > >react基礎篇四

react基礎篇四

但是 classname 使用 ring rec change 頁面 left mes

列表 & Keys

渲染多個組件

你可以通過使用{}在JSX內構建一個元素集合

下面,我們使用Javascript中的map()方法遍歷numbers數組。對數組中的每個元素返回<li>標簽,最後我們得到一個數組listItems

我們把整個listItems插入到ul元素中,然後渲染進DOM:

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById(‘root‘)
);
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最好是這個元素在列表中擁有的一個獨一無二的字符串。通常,我們使用來自數據的id作為元素的key

如果列表項目的順序可能會變化,我們不建議使用索引來用作鍵值,因為這樣做會導致性能的負面影響,還可能引起組件狀態問題。如果你想要了解更多,請點擊深度解析key的必要性。如果你選擇不指定顯式的鍵值,那麽React將默認使用索引用作為列表項目的鍵值。

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

key會作為給React的提示,但不會傳遞給你的組件。如果您的組件中需要使用和key相同的值,請用其他屬性名顯式傳遞這個值:

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

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

表單

HTML表單元素與React中的其他DOM元素有所不同,因為表單元素生來就保留一些內部狀態。例如,下面這個表單只接受一個唯一的name。

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

當用戶提交表單時,HTML的默認行為會使這個表單跳轉到一個新頁面。在React中亦是如此。但大多數情況下,我們都會構造一個處理提交表單並可訪問用戶輸入表單數據的函數。實現這一點的標準方法是使用一種稱為“受控組件”的技術。

受控組件

在HTML當中,像<input>,<textarea>, 和 <select>這類表單元素會維持自身狀態,並根據用戶輸入進行更新。但在React中,可變的狀態通常保存在組件的狀態屬性中,並且只能用 setState() 方法進行更新。

我們通過使react變成一種單一數據源的狀態來結合二者。React負責渲染表單的組件仍然控制用戶後續輸入時所發生的變化。相應的,其值由React控制的輸入表單元素稱為“受控組件”。

例如,我們想要使上個例子中在提交表單時輸出name,我們可以寫成“受控組件”的形式:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ‘‘};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert(‘A name was submitted: ‘ + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

在 CodePen 上嘗試。

由於 value 屬性是在我們的表單元素上設置的,因此顯示的值將始終為 React數據源上this.state.value 的值。由於每次按鍵都會觸發 handleChange 來更新當前React的state,所展示的值也會隨著不同用戶的輸入而更新。

使用”受控組件”,每個狀態的改變都有一個與之相關的處理函數。這樣就可以直接修改或驗證用戶輸入。例如,我們如果想限制輸入全部是大寫字母,我們可以將handleChange 寫為如下:

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});

在React應用中,對應任何可變數據理應只有一個單一“數據源”。通常,狀態都是首先添加在需要渲染數據的組件中。然後,如果另一個組件也需要這些數據,你可以將數據提升至離它們最近的共同祖先中。你應該依賴 自上而下的數據流,而不是嘗試在不同組件中同步狀態。

組合 vs 繼承(即slot)

包含關系

一些組件不能提前知道它們的子組件是什麽。這對於 SidebarDialog 這類通用容器尤其常見。

我們建議這些組件使用 children 屬性將子元素直接傳遞到輸出。

function FancyBorder(props) {
  return (
    <div className={‘FancyBorder FancyBorder-‘ + props.color}>
      {props.children}
    </div>
  );
}

這樣做還允許其他組件通過嵌套 JSX 來傳遞子組件。

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

雖然不太常見,但有時你可能需要在組件中有多個入口,這種情況下你可以使用自己約定的屬性而不是 children

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}
function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

在 CodePen 上試試。

類似 <Contacts /><Chat /> 這樣的 React 元素都是對象,所以你可以像任何其他元素一樣傳遞它們。

react基礎篇四