FrontPage

目次

useState

const [stateを格納する変数, stateの値を更新する関数] = useState(初期値)

Counter.js

import { useState } from 'react';

export default function Counter({ init }) {
   const [count, setCount] = useState(init);
   return (
      <>
         <p>{ count }</p>
         <button onClick={ () => setCount( c => c + 1 ) }>++</button>
      </>
   );
}

useRef

useReducer

useReducer(
   reducer,
   initialArg,
   init?
)
export default function Counter({init = 0}) {
   const [count, dispatch] = useReducer(
       (count, action) => {
           switch (action.type) {
               case 'increment':
                   return count + 1;
               case 'reset':
                   return init;
               default:
                   throw Error('Unknown action: ' + action.type);
           }
       },
       init
   );

   return (
       <>
           <p>{count}</p>
           <button onClick={() => dispatch({type: 'increment'})}>++</button>
           <button onClick={() => dispatch({type: 'reset'})}>reset</button>
       </>
   );
}

少し複雑な例
App.js

import {useReducer} from "react";
import AddNote from "./AddNote";
import NoteList from "./NoteList";

let initialNotes = [];

function notesReducer(notes, action) {
 switch (action.type) {
   case 'added': {
     return [...notes, {
       id: crypto.randomUUID(),
       text: action.text,
     }];
   }

   case 'edited': {
     return notes.map( e => {
       return e.id === action.note.id ? action.note : e;
     });
   }

   case 'deleted': {
     return notes.filter( e => e.id !== action.id);
   }

   default: {
     throw Error('Unknown action: ' + action.type);
   }
 }
}

export default function App() {
 const [notes, dispatch] = useReducer(
     notesReducer,
     initialNotes
 );

 // ノートを追加
 function handleAddNote(text) {
   dispatch({
     type: 'added',
     text: text,
   });
 }

 // ノートを編集
 function handleEditNote(note) {
   dispatch({
     type: 'edited',
     note: note,
   });
 }

 // ノートを削除
 function handleDeleteNote(id) {
   dispatch({
     type: "deleted",
     id: id,
   });
 }

 return (
     <>
       <h1>Notes</h1>
       <AddNote onAddNote={handleAddNote}/>
       <NoteList
         notes={notes}
         onEditNote={handleEditNote}
         onDeleteNote={handleDeleteNote}
       />
     </>
 );
}

AddNote.js

import {useState} from "react";

export default function AddNote({onAddNote}) {
   const [text, setText] = useState('');
   return (
       <>
           <input
               placeholder="ノートを追加"
               value={text}
               onChange={e => setText(e.target.value)}
           />
           <button onClick={() => {
               onAddNote(text);
               setText('');
           }}>追加</button>
       </>
   );
}

NoteList.js

import {useState} from "react";

export default function NoteList({
   notes,
   onEditNote,
   onDeleteNote,
}) {
   return (
       <>
           {notes.map(e => (
               <div key={e.id}>
                   <NoteRow
                       note={e}
                       onEdit={onEditNote}
                       onDelete={onDeleteNote}
                   />
               </div>
           ))}
       </>
   );
}

function NoteRow({
   note,
   onEdit,
   onDelete
}) {
   const [isEditing, setIsEditing] = useState(false);

   if (isEditing) {
       return (
           <>
               <input
                   value={note.text}
                   onChange={e => {
                       onEdit({
                           ...note,
                           text: e.target.value
                       });
                   }} />
               <button onClick={() => setIsEditing(false)}>
                   保存
               </button>
           </>
       );
   }
   else {
       return (
           <>
               {note.text}
               <button onClick={() => setIsEditing(true)}>
                   編集
               </button>
               <button onClick={() => onDelete(note.id)}>
                   削除
               </button>
           </>
       );
   }
}

useContext

const Contextオブジェクト = createContext(defaultValue);
const 値 = useContext(Contextオブジェクト);
import {createContext, useContext} from "react";

export const MessageContext = createContext('hello');

export default function Context() {
   return (
       <>
           {/* Context.Provider以下のコンポーネントではvalueの値になる */}
           <MessageContext.Provider value='hello world'>
               <Label /> {/* 'hello world'が描画される */}
           </MessageContext.Provider>

           {/* Context.Provider以下のコンポーネントでない場合はdefaultValueが使用される */}
           <Label /> {/* defaultValueの'hello'が描画される */}
       </>
   );
}

function Label() {
   return <Message />
}

function Message() {
   const message = useContext(MessageContext);
   return <p>{message}</p>
}

useEffect

useEffect(setup, dependencies?)
import {useEffect, useState} from "react";

export default function Weather({latitude='35.662422', longitude='139.590247'}) {
   const [data, setData] = useState(null);

   useEffect(() => {
       fetch(`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m&timezone=Asia%2FTokyo&forecast_days=1`)
           .then(response => response.json())
           .then(json => setData(`time:${json.current.time}, temperature:${json.current.temperature_2m}`));
   }, []);
 
   if (!data) {
       return <p>Loading...</p>
   }

   return <p>{data}</p>
}

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS