React.js 学习

目录

Source

Expression and statement:

React styling:

React Components

React props 

Mapping data to components

 Map/Filler/Reduce

Arrow function

Conditional/Ternary operator and &&

State in react --imperative or declarative 

React Hooks-use State

Array destructuring

Event Handling in React

React Forms

 Changing complex state

Spread syntax

实现加入todolist和删除todolist的功能

Keeper App project


Source

Web Development Course Resources | The App Brewery

Expression and statement:

Expression:always return something

const u = getvalue();
const u = 1;

Statement

if(u>2){
    return 
}
while(u>2){
return 
}

for(let i = 0 ;i<n;i++){
return
}

ES6中 template literals

Template literals are literals delimited with backtick (`) characters, allowing for multi-line stringsstring interpolation with embedded expressions, and special constructs called tagged templates.

LIke the template:


`string text ${expression} string text`

tagFunction`string text ${expression} string text`

 Code

<h1>Hello {`${name}${nums}`}</h1>

express/statement

Template literals (Template strings) - JavaScript | MDN

React styling:

主要就是一个内容:

可以通过设定变量,修改变量的值,然后使用ejs应用再html中

//Create a React app from scratch.
//Show a single h1 that says "Good morning" if between midnight and 12PM.24-12
//or "Good Afternoon" if between 12PM and 6PM. 12-18
//or "Good evening" if between 6PM and midnight. 18-24
//Apply the "heading" style in the styles.css
//Dynamically change the color of the h1 using inline css styles.
//Morning = red, Afternoon = green, Night = blue.

import React from "react";
import * as ReactDOM from "react-dom";

const date = new Date();
const currentTime = date.getHours();
let greeting;

const customStyle = {
  color: ""
};

if (currentTime < 12) {
  greeting = "Good Morning";
  customStyle.color = "red";
} else if (currentTime < 18) {
  greeting = "Good Afternoon";
  customStyle.color = "green";
} else {
  greeting = "Good Night";
  customStyle.color = "blue";
}

ReactDOM.render(
  <h1 className="heading" style={customStyle}>
    {greeting}
  </h1>,
  document.getElementById("root")
);

 Component 形式写的

import React from "react";
import ReactDOM from "react-dom";

var today = new Date();   
var time = today.getHours();

const redStyle = {
  color: 'red'
}
const greenStyle = {
  color: 'green'
  
}
const blueStyle = {
  color: 'blue'
}

const Get = function(time){
  if(time >0 && time <12){
    return <h1 className="heading" style={redStyle}>Good morning</h1>
  }else if(time >=12 && time <=18){
    return <h1 className="heading" style={greenStyle}>Good Afternoon</h1>
  }else{
    return <h1 className="heading" style={blueStyle}>Good evening</h1>
  }
}



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

React Components

How to make a components?

We can use function like Heading and then use <Heading />to cite components in the reactdom.render

import React from "react";
import ReactDOM from "react-dom";

function Heading(){
  return <h1>My Favourite Foods</h1>
}

ReactDOM.render(
  <div>
    <Heading />
    <ul>
      <li>Bacon</li>
      <li>Jamon</li>
      <li>Noodles</li>
    </ul>
  </div>,
  document.getElementById("root")
);

Using Jsx to make a components.

Firstly, create jsx file

and then write a function in the jsx file, next it needs to export funcition

List.jsx

import React from "react";

function List() {
  return (
    <div>
      <ul>
        <li>Bacon</li>
        <li>Jamon</li>
        <li>Noodles</li>
      </ul>
    </div>
  );
}
export default List;

In the main js file(index.js)

Need to import components into the file.

and use <List />..

import React from "react";
import ReactDOM from "react-dom";
import Heading from "./Heading.jsx";
import List from "./List.jsx";

ReactDOM.render(
  <div>
    <Heading />
    <List />
  </div>,
  document.getElementById("root")
);

How to write statement in the jsx file

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";

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

We can use some expression and return html in the file

Heading.jsx 

import React from "react";

function Heading() {
  const date = new Date();
  const currentTime = date.getHours();
  let greeting;

  const customStyle = {
    color: ""
  };

  if (currentTime < 12) {
    greeting = "Good Morning";
    customStyle.color = "red";
  } else if (currentTime < 18) {
    greeting = "Good Afternoon";
    customStyle.color = "green";
  } else {
    greeting = "Good Night";
    customStyle.color = "blue";
  }
  return (
    <h1 className="heading" style={customStyle}>
      {greeting}
    </h1>
  );
}
export default Heading;

App.jsx 

import React from "react";
import Heading from "./Heading.jsx";

function App() {
  return (
    <div>
      <Heading />)
    </div>
  );
}
export default App;

Import and export and modules 

We can use "import" to import something and we also can use var react = require("react") to import modules.

Import is EJS/ Require is node.js.They all can import modules. But we use "import " to import modules to be better. Because our web services all can be accepted. 

we put a list of what to import in curly braces import {...}, like this:

index.js

import React from "react";
import ReactDOM from "react-dom";
import pi, { doublePi, triplePi } from "./math.js";
// import * as Pi from "./math.js"; it is return an object

ReactDOM.render(
  <ul>
    //<li>{Pi.pi}</li>
    // <li>{Pi.doublePi()}</li>
    // <li>{Pi.triplePi()}</li>
    <li>{pi}</li>
    <li>{doublePi()}</li>
    <li>{triplePi()}</li>
  </ul>,
  document.getElementById("root")
);

Math.js

default just only one ,so we could change the name about the default varibale.

const pi = 3.1415926;

function doublePi() {
  return pi * 2;
}

function triplePi() {
  return pi * 3;
}

export default pi;
export { doublePi, triplePi };

Notice: 

when you write components,it would be better to capitalise initial character.

App.jsx

import React from "react";
import Footer from "./Footer";
import Note from "./Note";
import Header from "./Header";

function App(){
    return (
        <div>
            <Header />
            <Note />
            <Footer />
        </div>
    )
};
export default App;

React props 

When you write components,you want to reuse your components.Properties come in handy.

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";

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

App.jsx

import React from "react";
import Card from "./Card";
import contacts from "../contacts";

function App() {
  return (
    <div>
      <h1 className="heading">My Contacts</h1>
      <Card
        name={contacts[0].name}
        url={contacts[0].imgURL}
        tel={contacts[0].phone}
        ema={contacts[0].email}
      />
      <Card
        name={contacts[1].name}
        url={contacts[1].imgURL}
        tel={contacts[1].phone}
        ema={contacts[1].email}
      />
      <Card
        name={contacts[2].name}
        url={contacts[2].imgURL}
        tel={contacts[2].phone}
        ema={contacts[2].email}
      />
    </div>
  );
}

export default App;

 Components!!

Card.jsx

import React from "react";

function Card(props) {
  return (
    <div className="card">
      <div className="top">
        <h2 className="name">{props.name}</h2>
        <img className="circle-img" src={props.url} alt="avatar_img" />
      </div>
      <div className="bottom">
        <p className="info">{props.tel}</p>
        <p className="info">{props.ema}</p>
      </div>
    </div>
  );
}
export default Card;

 contacts.js

const contacts = [
  {
    name: "Beyonce",
    imgURL:
      "https://blackhistorywall.files.wordpress.com/2010/02/picture-device-independent-bitmap-119.jpg",
    phone: "+123 456 789",
    email: "b@beyonce.com"
  },
  {
    name: "Jack Bauer",
    imgURL:
      "https://pbs.twimg.com/profile_images/625247595825246208/X3XLea04_400x400.jpg",
    phone: "+987 654 321",
    email: "jack@nowhere.com"
  },
  {
    name: "Chuck Norris",
    imgURL:
      "https://i.pinimg.com/originals/e3/94/47/e39447de921955826b1e498ccf9a39af.png",
    phone: "+918 372 574",
    email: "gmail@chucknorris.com"
  }
];
export default contacts;

Mapping data to components

how to use loop in the components?

What matters is that the actual content has some unique identifier in case the elements are rerendered in a different order. index is almost always incorrect because indices are always ordered numerically where data is practically guaranteed not to be. 

"Map" function can loop one object.

Lists and Keys – React

If you want to use the unique id,you need to create a custom proporty.

App.jsx

import React from "react";
import Card from "./Card";
import contacts from "../contacts";

function createCard(contact) {
  return (
    <Card
      id={contact.id}
      key={contact.id}
      name={contact.name}
      img={contact.imgURL}
      tel={contact.phone}
      email={contact.email}
    />
  );
}

function App() {
  return (
    <div>
      <h1 className="heading">My Contacts</h1>
      {contacts.map(createCard)}
    </div>
  );
}

export default App;

Mapping Pratices

App.jsx 

import React from "react";
import Entry from "./Entry";
import emojipedia from "../emojipedia";
// create entry components
// create props to replace hardcoded data
// import emojipedia const
// map through the emojipedia array and render Entry components

function createList(list) {
  return (
    <Entry
      key={list.id}
      emoji={list.emoji}
      name={list.name}
      meaning={list.meaning}
    />
  );
}

function App() {
  return (
    <div>
      <h1>
        <span>emojipedia</span>
      </h1>

      <dl className="dictionary">{emojipedia.map(createList)}</dl>
    </div>
  );
}

export default App;

 Entry.jsx

import React from "react";

function Entry(props) {
  return (
    <div className="term">
      <dt>
        <span className="emoji" role="img" aria-label="Tense Biceps">
          {props.emoji}
        </span>
        <span>{props.name}</span>
      </dt>
      <dd>{props.meaning}</dd>
    </div>
  );
}
export default Entry;

emojipedia.js 

const emojipedia = [
  {
    id: 1,
    emoji: "💪",
    name: "Tense Biceps",
    meaning:
      "“You can do that!” or “I feel strong!” Arm with tense biceps. Also used in connection with doing sports, e.g. at the gym."
  },
  {
    id: 2,
    emoji: "🙏",
    name: "Person With Folded Hands",
    meaning:
      "Two hands pressed together. Is currently very introverted, saying a prayer, or hoping for enlightenment. Is also used as a “high five” or to say thank you."
  },
  {
    id: 3,
    emoji: "🤣",
    name: "Rolling On The Floor, Laughing",
    meaning:
      "This is funny! A smiley face, rolling on the floor, laughing. The face is laughing boundlessly. The emoji version of “rofl“. Stands for „rolling on the floor, laughing“."
  }
];
export default emojipedia;

 Map/Filler/Reduce

var numbers = [3, 56, 2, 48, 5];

//Map -Create a new array by doing something with each item in an array.

const result_map = numbers.map(function Multiplys(x) {
  return x * 2;
});
console.log(result_map);

//Filter - Create a new array by keeping the items that return true.
const result_filter = numbers.filter(function (x) {
  return x > 3;
});
console.log(result_filter);

//Reduce - Accumulate a value by doing something to each item in an array.
const result_reduce = numbers.reduce(function (accumulator, currentvalue) {
  return accumulator + currentvalue;
});
console.log(result_reduce);

//Find - find the first item that matches from an array.
const result_find = numbers.find(function (num) {
  return num > 10;
});
console.log(result_find);

//FindIndex - find the index of the first item that matches.
const result_index = numbers.findIndex(function (num) {
  return num > 10;
});
console.log(result_index);

Arrow function

var numbers = [3, 56, 2, 48, 5];

Map -Create a new array by doing something with each item in an array.
const newNumbers1 = numbers.map((x) => x * 2);

就是将函数全部改成匿名函数,将return 改为'=>'符号 

ES6 In Depth: Arrow functions - Mozilla Hacks - the Web developer blog

Conditional/Ternary operator and &&

 Conditional/Ternary operator

Syntax

condition ? exprIfTrue : exprIfFalse

 It means:

if (condition){
    True
}else{
    False
}

 Example:

const age = 26;
const beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"

Logical AND (&&) in react

Syntax:

condition && expression
true && expression
false && expression(no express)

State in react --imperative or declarative 

You probably have seen that React is declarative.

 imperative example(就是你说啥,他做啥,比较死板)

const container = document.getElementById('container'); 
const btn = document.createElement('按钮');
btn.className = 'btn 红'; 
btn.onclick = function(event) { 
if (this.classList.contains('red')) { 
   this.classList.remove('red'); 
   this.classList.add('blue'); 
} else { 
   this.classList.remove('blue'); 
   this.classList.add('红色'); 
} 
};
container.appendChild(btn);

 our declarative React example

class Button extends React.Component{
  this.state = { color: 'red' }
  handleChange = () => {
    const color = this.state.color === 'red' ? 'blue' : 'red';
    this.setState({ color });
  }
  render() {
    return (<div>
      <button 
         className=`btn ${this.state.color}`
         onClick={this.handleChange}>
      </button>
    </div>);
  }
}

 https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2

React Hooks-use State

当我们想点击一个按钮,然后更新一下点击数量,需要建立函数去更新count,还需要React render,这非常麻烦。

what means?

import React from "react";
import ReactDOM from "react-dom";

var count = 3;

function increase() {
  count++;
  console.log(count);
}

ReactDOM.render(
  <div className="container">
    <h1>0</h1>
    <button onClick={increase}>+</button>
  </div>,
  document.getElementById("root")
);

没有办法直接显示在页面,需要render 一下reactdom

import React from "react";
import ReactDOM from "react-dom";

var count = 0;

function increase() {
  count++;
  ReactDOM.render(
    <div className="container">
      <h1>{count}</h1>
      <button onClick={increase}>+</button>
    </div>,
    document.getElementById("root")
  );
}

ReactDOM.render(
  <div className="container">
    <h1>0</h1>
    <button onClick={increase}>+</button>
  </div>,
  document.getElementById("root")
);

此时我们可以用上函数useState(),就再也不用使用reactdom.render,more efficient.

就是说,使用array destructuring来记录count 和 setcount

import React, { useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  function increase() {
    setCount(count + 1);
  }
  function decrease() {
    setCount(count - 1);
  }

  return (
    <div className="container">
      <h1>{count}</h1>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  );
}

export default App;

 

Hooks API Reference – React

 

Common Mistakes

Good

<button onClick={sayHello}>
  Click me!
</button>

Bad

<button onClick={sayHello()}>
  Click me!
</button>

 

good!

<button onClick={() => functionName())}>
  Click me!
</button>

Bad

<button onClick={() => functionName}>
  Click me!
</button>

 

React onClick Event Handling (With Examples) - Upmostly

Pratice:

//Challenge:
//1. Given that you can get the current time using:
// let time = new Date().toLocaleTimeString();
// console.log(time);
//Show the latest time in the <h1> when the Get Time button
//is pressed.

//2. Given that you can get code to be called every second
//using the setInterval method.
//Can you get the time in your <h1> to update every second?

//e.g. uncomment the code below to see Hey printed every second.
// function sayHi() {
//   console.log("Hey");
// }
// setInterval(sayHi, 1000);

Answer:

import React, { useState } from "react";

function App() {
  setInterval(getnewTime, 1000);
  let now = new Date().toLocaleTimeString();
  const [time, setTime] = useState(now);
  function getnewTime() {
    let newTime = new Date().toLocaleTimeString();
    setTime(newTime);
  }
  function sayHi() {
    console.log("Hey");
  }
  return (
    <div className="container">
      <h1>{time}</h1>
      <button onClick={getnewTime}>Get Time</button>
    </div>
  );
}

Array destructuring

// destructuring Array
const [cat, dog] = animals;

// destructuring object
// const { name, sound } = cat;
// const { name: catname, sound: catsount } = cat;
// const { name = "fluddy", sound = "iiii" } = cat;

Destructuring assignment - JavaScript | MDN

Event Handling in React

我们需要实现,当你的鼠标放在button上面的时候,他的颜色会从黑变成白色

这里很巧妙,使用了true和false 来标记状态

还是用了多元运算符来判断

import React, { useState } from "react";

function App() {
  const [headingText, setheadingText] = useState("Hello");
  const [isMouseOver, setIsMouseOver] = useState(false);
  function handleClick() {
    setheadingText("Submitted");
  }

  function handleMouseOver() {
    setIsMouseOver(true);
  }
  function handleMouseOut() {
    setIsMouseOver(false);
  }
  return (
    <div className="container">
      <h1>{headingText}</h1>
      <input type="text" placeholder="What's your name?" />
      <button
        onClick={handleClick}
        onMouseOver={handleMouseOver}
        onMouseOut={handleMouseOut}
        style={{ backgroundColor: isMouseOver ? "black" : "white" }}
      >
        Submit
      </button>
    </div>
  );
}

export default App;

React Forms

点击表单,触发click事件有两种方法

第一个是设置button 的onclick事件

 <button onClick={handleClick}>Submit</button>

第二种是使用form表单的属性 

onsubmit 属性

import React, { useState } from "react";

function App() {
  const [name, setName] = useState("");
  const [headingText, setHeading] = useState("");
  function handleChange(event) {
    setName(event.target.value);
  }
  function handleClick() {
    setHeading(name);
  }
  return (
    <div className="container">
      <h1>Hello {headingText}</h1>
      <form onSubmit={handleClick}>
        <input
          onChange={handleChange}
          type="text"
          placeholder="What's your name?"
          value={name}
        />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

export default App;

但是他会刷新事件,过几秒钟,就刷新一下

  function handleClick(event) {
    setHeading(name);
    event.preventDefault();
  }

完整代码 

import React, { useState } from "react";

function App() {
  const [name, setName] = useState("");
  const [headingText, setHeading] = useState("");
  function handleChange(event) {
    setName(event.target.value);
  }
  function handleClick(event) {
    setHeading(name);
    event.preventDefault();
  }
  return (
    <div className="container">
      <h1>Hello {headingText}</h1>
      <form onSubmit={handleClick}>
        <input
          onChange={handleChange}
          type="text"
          placeholder="What's your name?"
          value={name}
        />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

export default App;

Class Component/functional Component

import React, { useState } from "react";

function FunctionalComponent() {
  const [count, setCount] = useState(0);

  function increase() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increase}>+</button>
    </div>
  );
}

export default FunctionalComponent;

 ClassComponent:

import React from "react";

class ClassComponent extends React.Component {
  constructor() {
    super();
    this.state = {
      count: 0
    };
    this.increase = this.increase.bind(this);
  }

  increase() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <h1>{this.state.count}</h1>
        <button onClick={this.increase}>+</button>
      </div>
    );
  }
}

export default ClassComponent;

React Class Components

这两种component的效果都是一样的。Classcomponents中的render( )用来返回html元素

 Changing complex state

在useState建立object对象,可以直接更新三个元素

event.target.name 代表的是fName,这种元素。

然后需要同时更新三个值,不然的话,会被全部清零

import React, { useState } from "react";

function App() {
  const [contact, setContact] = useState({
    fName: "",
    lName: "",
    email: ""
  });

  function handleChange(event) {
    const { name, value } = event.target;

    setContact((prevValue) => {
      if (name === "fName") {
        return {
          fName: value,
          lName: prevValue.lName,
          email: prevValue.email
        };
      } else if (name === "lName") {
        return {
          fName: prevValue.fName,
          lName: value,
          email: prevValue.email
        };
      } else if (name === "email") {
        return {
          fName: prevValue.fName,
          lName: prevValue.lName,
          email: value
        };
      }
    });
  }

  return (
    <div className="container">
      <h1>
        Hello {contact.fName} {contact.lName}
      </h1>
      <p>{contact.email}</p>
      <form>
        <input name="fName" placeholder="First Name" onChange={handleChange} />
        <input name="lName" placeholder="Last Name" onChange={handleChange} />
        <input name="email" placeholder="Email" onChange={handleChange} />
        <button>Submit</button>
      </form>
    </div>
  );
}

export default App;

Spread syntax

加三个点,即可完成填补的功能

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

console.log(sum.apply(null, numbers));
// expected output: 6

Spread syntax (...) - JavaScript | MDN

 Pushing those objects into an array, you need to use '[   ]'

 JavaScript set object key by variable

 index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";

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

//CHALLENGE: Make this app work by applying what you've learnt.
//1. When new text is written into the input, its state should be saved.
//2. When the add button is pressed, the current data in the input should be
//added to an array.
//3. The <ul> should display all the array items as <li>s

 App.jsx

import React, { useState } from "react";

function App() {
  const [inputText, setInputText] = useState("");
  const [items, setItems] = useState([]);

  function handleChange(event) {
    const newValue = event.target.value;
    setInputText(newValue);
  }
  function addItem() {
    setItems((prevValue) => {
      return [...prevValue, inputText];
    });
    setInputText("");
  }
  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input type="text" onChange={handleChange} value={inputText} />
        <button onClick={addItem}>
          <span>Add</span>
        </button>
      </div>
      <div id="root">
        <ul>
          {items.map((todoItem) => {
            return <li>{todoItem}</li>;
          })}
        </ul>
      </div>
    </div>
  );
}

export default App;

实现加入todolist和删除todolist的功能

App.jsx 

import React, { useState } from "react";
import ToDoItem from "./ToDoItem";

function App() {
  const [inputText, setInputText] = useState("");
  const [items, setItems] = useState([]);

  function handleChange(event) {
    const newValue = event.target.value;
    setInputText(newValue);
  }

  function addItem() {
    setItems((prevItems) => {
      return [...prevItems, inputText];
    });
    setInputText("");
  }
  function deletItem(id) {
    setItems((prevItem) => {
      return prevItem.filter((item, index) => {
        return index !== id;
      });
    });
  }

  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input onChange={handleChange} type="text" value={inputText} />
        <button onClick={addItem}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {items.map((todoItem, index) => (
            <ToDoItem
              key={index}
              id={index}
              text={todoItem}
              onChecked={deletItem}
            />
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

 Todoltem.jsx

import React, { useState } from "react";

function ToDoItem(props) {
  return (
    <div
      onClick={() => {
        props.onChecked(props.id);
      }}
    >
      <li>{props.text}</li>
    </div>
  );
}

export default ToDoItem;

Keeper App project

completed code

App.jsx

import React, { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";

function App() {
  const [notes, setNotes] = useState([]);
  function addNote(newNote) {
    setNotes((prevValue) => {
      return [...prevValue, newNote];
    });
  }
  function deleteNote(id) {
    setNotes((prevValue) => {
      return prevValue.filter((items, index) => {
        return index !== id;
      });
    });
  }
  return (
    <div>
      <Header />
      {/* pass the new note back to the App */}
      <CreateArea onAdd={addNote} />
      {notes.map((noteItem, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteNote}
          />
        );
      })}
      <Note
        key={1}
        title="Note title"
        content="Note content"
        onDelete={deleteNote}
      />
      <Footer />
    </div>
  );
}

export default App;

Note.jsx

import React from "react";

function Note(props) {
  function handleClick() {
    props.onDelete(props.id);
  }
  return (
    <div className="note">
      <h1>{props.title}</h1>
      <p>{props.content}</p>
      <button onClick={handleClick}>DELETE</button>
    </div>
  );
}

export default Note;

 CreateArea.jsx

import React, { useState } from "react";

function CreateArea(props) {
  // create a constant
  const [note, setNote] = useState({
    title: "",
    content: ""
  });
  function handleChange(event) {
    // keeps track of the title and content
    const { name, value } = event.target;
    setNote((prevValue) => {
      return {
        // get previous value and update new value
        ...prevValue,
        [name]: value
      };
    });
  }
  function submitNote(event) {
    //pass the note back to the App
    props.onAdd(note);
    setNote({
      title: "",
      content: ""
    });
    // When you click submit button,it will refresh
    event.preventDefault();
  }
  return (
    <div>
      <form>
        <input
          name="title"
          placeholder="Title"
          value={note.title}
          onChange={handleChange}
        />
        <textarea
          name="content"
          placeholder="Take a note..."
          rows="3"
          value={note.content}
          onChange={handleChange}
        />
        <button onClick={submitNote}>Add</button>
      </form>
    </div>
  );
}

export default CreateArea;

Target:

//CHALLENGE:

//1. Implement the add note functionality.

//- Create a constant that keeps track of the title and content.

//- Pass the new note back to the App.

//- Add new note to an array.

//- Take array and render seperate Note components for each item.

 Create a constant that keeps track of the title and content.

const [note, setNote] = useState({
    title: "",
    content: ""
  });
  function handleChange(event) {
    const { name, value } = event.target;
    setNote((prevValue) => {
      return {
        ...prevValue,
        [name]: value
      };
    });
  }

 Pass the new note back to the App.

 1.需要在button设置click

<button onClick={submitNote}>Add</button>

2.需要触发函数,这个函数可以帮助传送数据到app.jsx中,props可以帮助传送数据

function submitNote(event) {
    props.onAdd(note);
    event.preventDefault();
  }

3.在app中加入传送数据的函数,并加上接收的函数

function addItem(note) {
    console.log(note);
  }
  return (
    <div>
      <Header />
      <CreateArea onAdd={addItem} />
      <Note key={1} title="Note title" content="Note content" />
      <Footer />
    </div>
  );

 Add new note to an array

 const [newNote, setNewNote] = useState([]);
  function addItem(note) {
    setNewNote((prevValue) => {
      return [...prevValue, note];
    });
  }

 使用数组存放数据,并且使用接受数据的那个值,使用spread operator去存放数据到数组中

T ake array and render seperate Note components for each item.

,可以从map中获取index值

{newNote?.map((noteItem, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteItem}
          />
        );
      })}

//2. Implement the delete note functionality.

//- Callback from the Note component to trigger a delete function.

//- Use the filter function to filter out the item that needs deletion.

//- Pass a id over to the Note component, pass it back to the App when deleting.

//This is the end result you're aiming for:

//https://pogqj.csb.app/

//2. Implement the delete note functionality.

//- Callback from the Note component to trigger a delete function.

function Note(props) {
  function deleteNote() {
    props.ondelete();
  }
  return (
    <div className="note">
      <h1>{props.title}</h1>
      <p>{props.content}</p>
      <button onClick={deleteNote}>DELETE</button>
    </div>
  );

//- Use the filter function to filter out the item that needs deletion.

filter需要return 值,不然会报错

function deleteItem(id) {
    setNewNote((prevValue) => {
      return prevValue.filter((items, index) => {
        return index !== id;
      });
    });
  }

//- Pass a id over to the Note component, pass it back to the App when deleting.

map 函数有自带index 属性,可以直接给他i

function handleClick() {
    props.onDelete(props.id);
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值