Medium裡面的react相關文章記錄

flower_emma發表於2018-09-27

1.All the fundamental React.js concepts, jammed into this single Medium article

這篇簡單Medium文章包含了所有基本的react.js概念(下面程式碼都摘自原文 詳細瞭解請閱讀原文)

基本概念#1:React就是元件 (React is all about components)

React是圍繞可複用元件(resuable components)的概念設計的。你可以定義小元件然後組合成更大的元件。即使在不同專案中,所有大型或者小型的元件都可以重複使用。一個react元件-最簡單的形式-就是一個簡單javaScript函式(a plain-old javaScript function)

// 例子 1
// https://jscomplete.com/repl?j=Sy3QAdKHW
function Button (props){
    //如:return 一個 dom 元素
    return <button type ="submit">{props.lable}</button>
}  

//將Button元件在瀏覽器中渲染
ReactDOM.render(<Button label = "save" />, mountNode)
複製程式碼

請注意下面關於例子1:

  • 元件的名字要以大寫字母開頭。這一要求是為了在混合使用HTML元素跟React元素時,區分它們。
  • 每一個元件可以有屬性列表,就像跟HTML元素一樣。在react中,這個列表的名字稱為props。
  • 我們看到上面Button元件的返回輸出值看起來像HTML的形式。它既不javaSCript也不是HTML,甚至不是react.js。但是,它很受歡迎,成為了react應用程式的預設設定。它叫做JSX,是javascript的擴充套件。

基本概念#2:JSX的變化是什麼(What the flux is JSX)

下面是例子1不用JSX語法:

// 例子 2 - 
// https://jscomplete.com/repl?j=HyiEwoYB-
function Button (props) {
  return React.createElement(
    "button",
    { type: "submit" },
    props.label
  );
}
// 
ReactDOM.render(
  React.createElement(Button, { label: "Save" }),
  mountNode
);
複製程式碼

createElement是react 中的API,creactElement 實際上就是建立樹

// 例子 3 
// https://jscomplete.com/repl?j=r1GNoiFBb
const InputForm = React.createElement(
  "form",
  { target: "_blank", action: "https://google.com/search" },
  React.createElement("div", null, "Enter input and click Search"),
  React.createElement("input", { name: "q", className: "input" }),
  React.createElement(Button, { label: "Search" })
);
// InputForm 
function Button (props) {
  return React.createElement(
    "button",
    { type: "submit" },
    props.label
  );
}
// 
ReactDOM.render(InputForm, mountNode);
複製程式碼

請注意以下幾點:

  • InputForm 不是react元件,它是react元素。這是為什麼我們在ReactDOM.render的時候直接使用,而沒有使用<InputForm />形式
  • React.createElement函式在第一第二引數之後接受多個引數。 從第三個開始引數列表是包含建立子元素的
  • 當元素不需要任何屬性或者props的時候,React.createElement的第二個引數可以是null 或者空物件
  • 我們可以將HTML元素和React元素混合使用
  • React API 嘗試儘可能的接近DOM API

我們習慣看或者寫HTML形式,所以採用接近HTML的語法形式 JSX

// 例子 4 - JSX (跟例3 比較)
// https://jscomplete.com/repl?j=SJWy3otHW
const InputForm =
  <form target="_blank" action="https://google.com/search">
    <div>Enter input and click Search</div>
    <input name="q" className="input" />
    <Button label="Search" />
  </form>;

function Button (props) {
  // Returns a DOM element here. For example:
  return <button type="submit">{props.label}</button>;
}
// 
ReactDOM.render(InputForm, mountNode);
複製程式碼

請注意以下幾點:

  • 這不是HTML,比如這裡是用className 代替class
  • 考慮將上面看似HTML的形式看作javascript,可以看到在最後新增了分號

上面寫的例4形式是JSX,而瀏覽器看到的相當於它的編譯版本例3。所以,我們需要前處理器(pre-processor)將就JSX版本的轉換成React.createElement

順便說一句,JSX可以單獨使用,它不是 React-only

基本概念#3:可以在JSX中任何地方使用javaScipt表示式

在JSX中,你可以使用任何javaScript表示式,用一對花括號(curly braces)包圍

// 例5
// https://jscomplete.com/repl?j=SkNN3oYSW
const RandomValue = () => 
 <div>
   { Math.floor(Math.random() * 100) }
 </div>;
// 
ReactDOM.render(<RandomValue />, mountNode);
複製程式碼

在花括號內,寫入任何javaScript表示式,這種形式類似於 javaScript的模板語法${}
JSX 的唯一約束就是: 只能是表示式。因此,我們不能使用常規的if語句,需要使用三目表示式(ternary expression) javaScript 變數(variable)也是表示式(expression),所以元件接收的props ,需要放在 花括號中
javaScript 物件也是表示式。有時我們在花括號內使用javaScript物件,這使它看起來像花括號,但其實它是花括號內寫入的物件。一個例子就是在React中我們將CSS樣式物件傳遞給style屬性

// 列6
// https://jscomplete.com/repl?j=S1Kw2sFHb
const ErrorDisplay = ({message}) =>
 <div style={ { color: 'red', backgroundColor: 'yellow' } }>
   {message}
 </div>;

ReactDOM.render(
 <ErrorDisplay 
   message="These aren't the droids you're looking for" 
 />,
 mountNode
);
複製程式碼

在jSX也可以使用React元素,因為這個它也是一個表達。請記住React元素本質上是函式呼叫

// 例7 - 在 {}使用 react元素
// https://jscomplete.com/repl?j=SkTLpjYr-
const MaybeError = ({errorMessage}) =>
 <div>
   {errorMessage && <ErrorDisplay message={errorMessage} />}
 </div>;
 
const ErrorDisplay = ({message}) =>
 <div style={ { color: 'red', backgroundColor: 'yellow' } }>
   {message}
 </div>;

ReactDOM.render(
 <MaybeError
   errorMessage={Math.random() > 0.5 ? 'Not good' : ''}
 />,
 mountNode
);
複製程式碼

你也可以在JSX中使用javaScript的集合(collection)方法(map,reduce,filter,concat,等等),因為它們返回的也是表示式

// 例8- 在 {}使用 陣列map
// https://jscomplete.com/repl?j=SJ29aiYH-
const Doubler = ({value=[1, 2, 3]}) =>
 <div>
   {value.map(e => e * 2)}
 </div>;
ReactDOM.render(<Doubler />, mountNode);
複製程式碼

基本概念#4:你可以用class 來寫React 元件

// Example 9 - 使用class寫react元件
// https://jscomplete.com/repl?j=ryjk0iKHb
class Button extends React.Component {
render() {
  return <button>{this.props.label}</button>;
}
}
ReactDOM.render(<Button label="Save" />, mountNode);
複製程式碼
// 例 10 - 
// https://jscomplete.com/repl?j=rko7RsKS-
class Button extends React.Component {
constructor(props) {
  super(props);
  this.id = Date.now();
}
render() {
  return <button id={this.id}>{this.props.label}</button>;
 }
}
ReactDOM.render(<Button label="Save" />, mountNode);
複製程式碼
// 例 11 
// https://jscomplete.com/repl?j=H1YDCoFSb
  class Button extends React.Component {
    clickCounter = 0;
    handleClick = () => {
      console.log(`Clicked: ${++this.clickCounter}`);
    };
    
    render() {
      return (
        <button id={this.id} onClick={this.handleClick}>
          {this.props.label}
        </button>
      );
    }
  }
  // Use it
  ReactDOM.render(<Button label="Save" />, mountNode);
複製程式碼

基本概念#5:React事件:兩個重要的差異

// 例 12 
// https://jscomplete.com/repl?j=HkIhRoKBb
class Form extends React.Component {
handleSubmit = (event) => {
  event.preventDefault();
  console.log('Form submitted');
};

render() {
  return (
    <form onSubmit={this.handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}
}
ReactDOM.render(<Form />, mountNode);

複製程式碼

基本概念#6: ( Every React component has a story)

基本概念#7: React元件有私有狀態

// 例子 13 -  
// https://jscomplete.com/repl?j=H1fek2KH-
class CounterButton extends React.Component {
state = {
 clickCounter: 0,
 currentTimestamp: new Date(),
};

handleClick = () => {
 this.setState((prevState) => {
  return { clickCounter: prevState.clickCounter + 1 };
 });
};

componentDidMount() {
setInterval(() => {
  this.setState({ currentTimestamp: new Date() })
 }, 1000);
}

render() {
 return (
   <div>
     <button onClick={this.handleClick}>Click</button>
     <p>Clicked: {this.state.clickCounter}</p>
     <p>Time: {this.state.currentTimestamp.toLocaleString()}</p>
   </div>
 );
}
}
ReactDOM.render(<CounterButton />, mountNode);
複製程式碼

基本概念#8: react will react

基本概念#9: React is your agent

基本概念#10: Every React component has a story (part 2)

相關文章