iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
0
Modern Web

使用 React 製作簡易專案管理網站:從基礎到實戰系列 第 25

[Day 25] React 攻城戰 - 加入編輯標題功能

  • 分享至 

  • xImage
  •  

上一篇文章中,我們建立了一個簡單的根元件 App,並且使用 useReducer 將網站標題顯示出來:

import React from 'react';

import { reducer, initialState } from './reducer'; 

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  
  return (
    <div>
      <h1>{state.title}</h1>
    </div>
  );
};

export default App;

切換編輯模式

首先我們希望在點擊標題時可以將純文字變成文字輸入框以便修改,所以需要使用 useState 建立一個 state 來控制現在是純文字還是文字輸入框的狀態 ( useState 的使用方式可以參考之前一篇文章):

import React from 'react';

import { reducer, initialState } from './reducer'; 

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  
  const [isEditing, setIsEditing] = React.useState(false);
  
  return (
    <div>
      {isEditing ? <input value={state.title} /> : <h1>{state.title}</h1>}
    </div>
  );
};

export default App;

接著將 isEditing 這個 state 在標題被點擊時設成 true,按下 Enter 時則設成 false:

import React from 'react';

import { reducer, initialState } from './reducer'; 

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  
  const [isEditingTitle, setIsEditingTitle] = React.useState(false);
  
  return (
    <div>
      {isEditingTitle ? (
        <input
          value={state.title}
          // 加上 autoFocus 屬性讓文字輸入框自動出現游標
          autoFocus
          // 偵測按下 Enter 的事件
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingTitle(false);
            }
          }}
        />
      ) : (
        <h1
          // 偵測被滑鼠點擊的事件
          onClick={() => setIsEditingTitle(true)}
        >{state.title}</h1>
      )}
    </div>
  );
};

export default App;

編輯標題功能

再來要讓標題有編輯的功能。偵測文字輸入框 onChange 事件,在事件發生時呼叫 dispatch 傳入 action 物件(在之前一篇文章中定義過修改標題的 action 物件):

import React from 'react';

import { reducer, initialState } from './reducer'; 

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  
  const [isEditingTitle, setIsEditingTitle] = React.useState(false);
  
  return (
    <div>
      {isEditingTitle ? (
        <input
          value={state.title}
          autoFocus
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingTitle(false);
            }
          }}
          // 偵測文字內容改變的事件
          onChange={e => {
            dispatch({
              type: "CHANGE_TITLE",
              payload: {
                title: e.target.value
              }
            });
          }}
        />
      ) : (
        <h1
          onClick={() => setIsEditingTitle(true)}
        >{state.title}</h1>
      )}
    </div>
  );
};

export default App;

同步網頁標題

接著我們希望網站標題文字可同步到網頁的標題。使用 useEffect:

import React from 'react';

import { reducer, initialState } from './reducer'; 

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  
  const [isEditingTitle, setIsEditingTitle] = React.useState(false);
  
  // 每當 state.title 變化就會更新到 document.title
  React.useEffect(() => {
    document.title = state.title;
  }, [state.title]);
  
  return (
    <div>
      {isEditingTitle ? (
        <input
          value={state.title}
          autoFocus
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingTitle(false);
            }
          }}
          onChange={e => {
            dispatch({
              type: "CHANGE_TITLE",
              payload: {
                title: e.target.value
              }
            });
          }}
        />
      ) : (
        <h1
          onClick={() => setIsEditingTitle(true)}
        >{state.title}</h1>
      )}
    </div>
  );
};

export default App;

成果畫面

下集預告

建立新增看板的元件。


上一篇
[Day 24] React 攻城戰 - 根元件和全局樣式
下一篇
[Day 26] React 攻城戰 - 加入新增看板功能
系列文
使用 React 製作簡易專案管理網站:從基礎到實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言