Antデザインを使用してReactで美しいUIを作成する
Ant Design は、エレガントなユーザーインターフェイスを構築するのに役立つ多数の使いやすいコンポーネントを備えたReactUIライブラリです。
中国のコングロマリットAlibabaによって作成されたAntDesignは、Alibaba(もちろん)、Tencent、Baiduなどのいくつかの有名企業で使用されています。 Material-UIはGithubで4万個以上の星を獲得した最も人気のあるReactUIライブラリですが、 Ant Design は現在すぐ近くにあり、すぐにギャップを埋めています。
Ant Designのモバイルバージョンもあり、ここで詳細を学ぶことができます。
入門
このチュートリアルでは、AntDesignのコンポーネントのいくつかを紹介するための基本的なtodoアプリケーションを作成します。 最初のステップは、ボイラープレートを設定することです。 create-react-appを使用してこれを行いました。
次に、antd依存関係をプロジェクトに追加する必要があります。
$ yarn add antd # or, using npm: $ npm install antd --save
<Todo />コンポーネントの構築を開始する前に、ルートコンポーネントにそのコンポーネントへの参照を追加します。
index.js
import React from "react";
import ReactDOM from "react-dom";
import Todo from "./todo";
import "./styles.css";
function App() {
return (
<div className="App">
<Todo />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Todoコンポーネントの構築
これで、<Todo />コンポーネントの構築を開始できます。 次の内容のtodo.jsという名前の新しいファイルを開きます。
todo.js
import React from "react";
export default class Todo extends React.Component {
render() {
return (
<div className="todoContainer">
<h1>TODO App</h1>
</div>
);
}
}
.todoContainerがページの中央にうまく配置されるようにスタイルシートを編集します。
styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.todoContainer {
width: 75%;
margin-left: auto;
margin-right: auto;
}
涼しい! 次に、<Todo />コンポーネントに入力を追加しましょう。 antdで提供されているものを使用し、ライブラリのCSSファイルもインポートするようにします。
todo.js
import React from "react";
import { Input } from "antd";
// Don't forget to include the CSS styles for antd!
import "antd/dist/antd.css";
export default class Todo extends React.Component {
render() {
return (
<div className="todoContainer" />
<h1>TODO App</h1>
<Input
placeholder="What needs to be done?"
/>
</div>
);
}
}
これで、テキスト入力ボックスをレンダリングしています。 ただし、何もしません。 ToDoのリストをレンダリングできるように、コンポーネントの状態にコンテンツを追加するための入力が必要です。 <Input />のonPressEnter小道具を使用して、ユーザーが新しいToDoを送信したことを検出します。
todo.js
// --- snip ---
export default class Todo extends React.Component {
constructor() {
super();
// Initialize the state
this.state = {
todos: []
};
}
handlePressEnter = e => {
// Create a todo object containing its index and content
const todo = {
index: this.state.todos.length,
content: e.target.value
};
// Add the todo to our array
const newTodos = this.state.todos.concat(todo);
this.setState({
todos: newTodos
});
// Clear input
e.target.value = "";
};
render() {
return (
<div className="todoContainer">
<h1>TODO App</h1>
<Input
placeholder="What needs to be done?"
onPressEnter={this.handlePressEnter}
/>
</div>
);
}
}
これで、handlePressEnter()は、ユーザーが新しいToDoアイテムを入力するたびにコンポーネントの状態を更新しますが、それでもレンダリングする必要があります。
この目的のために、AntDesignの<List />コンポーネントを使用できます。 dataSourceプロップとして配列を受け取り、renderItemプロップに渡される関数に従って配列をレンダリングします。
todo.js
import React from "react";
import { Input, List } from "antd";
import "antd/dist/antd.css";
export default class Todo extends React.Component {
// --- snip ---
render() {
return (
<div className="todoContainer">
<h1>TODO App</h1>
<Input
placeholder="What needs to be done?"
onPressEnter={this.handlePressEnter}
/>
<List
{/* emptyText sets the text to display in an empty list */}
locale={{ emptyText: "No todo items" }}
dataSource={this.state.todos}
renderItem={item => (
<List.Item>{item.content}</List.Item>
)}
/>
</div>
);
}
}
タダ! これで、基本的なtodoアプリが機能するようになりました。 ただし、それを改善するためにできることはまだまだあります。
ファンシーになる
ToDoアプリケーションが稼働しています。 ただし、追加する必要があるものは他にもあります。最も重要なのは、削除ボタンです。 日付ピッカーも追加します。なぜですか?
<Todo />が過度に複雑になるのを避けるために、<List.Item />を独自の個別のコンポーネントに抽出します。 また、新しいメソッドremoveTodo()を定義して、インデックスが指定されたToDoアイテムを削除します。 次に、そのメソッドを新しいコンポーネントに渡します。
削除ボタンとして機能するために、Antの<Icon />コンポーネントを使用できます。 これを<List.Item />'のaction小道具に追加します。この小道具はコンポーネントの配列を取ります。 アイコンの完全なリストを表示するには、AntDesignWebサイトのこのページを参照してください。
todo.js
import React from "react";
import { Input, List, Icon } from "antd";
import "antd/dist/antd.css";
export default class Todo extends React.Component {
// --- snip ---
removeTodo = index => {
let newTodos = [...this.state.todos];
// Remove element
newTodos.splice(index, 1);
// Decrement greater indexes
for (let i = index; i < newTodos.length; i++) {
newTodos[i].index -= 1;
}
// Update state
this.setState({
todos: newTodos
});
};
render() {
return (
<div className="todoContainer">
<h1>TODO App</h1>
<Input
placeholder="What needs to be done?"
onPressEnter={this.handlePressEnter}
/>
<List
locale={{ emptyText: "No todo items" }}
dataSource={this.state.todos}
renderItem={item => (
<TodoItem
todo={item}
removeTodo={this.removeTodo}
/>
)}
/>
</div>
);
}
}
class TodoItem extends React.Component {
remove = () => {
// Remove this TodoItem
this.props.removeTodo(this.props.todo.index);
};
render() {
return (
<List.Item
actions={[
<Icon
type="close-circle"
theme="filled"
onClick={this.remove}
/>
]}
>
{this.props.todo.content}
</List.Item>
);
}
}
素晴らしい! あとは、Antの<DatePicker />コンポーネントを追加するだけです。 そのために、handlePressEnter()メソッドを更新してdateおよびdateStringプロパティを状態に保存しているtodoオブジェクトに追加します。 次に、これらのプロパティを更新するための追加のメソッドsetDate()が必要になります。
todo.js
import React from "react";
import { Input, List, Icon, DatePicker } from "antd";
import "antd/dist/antd.css";
export default class Todo extends React.Component {
// --- snip ---
handlePressEnter = e => {
// Create a todo object containing its index, content,
// as well as an empty date
const todo = {
index: this.state.todos.length,
content: e.target.value,
date: null,
dateString: ""
};
// Add the new todo to our array
const newTodos = this.state.todos.concat(todo);
this.setState({
todos: newTodos
});
// Clear input
e.target.value = "";
};
setDate = (index, date, dateString) => {
// Set the date of the given todo
let newTodos = [...this.state.todos];
newTodos[index].date = date;
newTodos[index].dateString = dateString;
// Initialize the state
this.setState({
todos: newTodos
});
};
render() {
return (
<div className="todoContainer">
<h1>TODO App</h1>
<Input
placeholder="What needs to be done?"
onPressEnter={this.handlePressEnter}
/>
<List
locale={{ emptyText: "No todo items" }}
dataSource={this.state.todos}
renderItem={item => (
<TodoItem
todo={item}
removeTodo={this.removeTodo}
setDate={this.setDate}
/>
)}
/>
</div>
);
}
}
class TodoItem extends React.Component {
remove = () => {
// Remove this TodoItem
this.props.removeTodo(this.props.todo.index);
};
handleDateChange = (date, dateString) => {
// Update the date when changed
this.props.setDate(this.props.todo.index, date, dateString);
}
render() {
return (
<List.Item
actions={[
<DatePicker
format="MM/DD/YYYY"
onChange={this.handleDateChange}
value={this.props.todo.date}
/>,
<Icon
type="close-circle"
theme="filled"
onClick={this.remove}
/>
]}
>
{this.props.todo.content}
</List.Item>
);
}
}
そして、voilà! 🎉
これで、AntDesignを利用した完全に機能するtodoアプリができました。 Antについて詳しく知りたい場合は、ドキュメントをご覧ください。
この投稿の完全なコードはCodeSandboxにあります。