の続きです。
ボタン操作
以下のようにしてボタンをクリックして関数を起動させることができます。次のコードではボタンを押すと関数handleClickが実行されて、コンソールに"I was clicked!"と表示されます。
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
function handleClick() {
console.log("I was clicked!")
}
return (
<div className="container">
<button onClick={handleClick}>Click me</button>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
マウスオーバー操作
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
const ImgPath=require("./images/cat1.png");
function handleOnMouseOver() {
console.log("MouseOver")
};
return (
<div className="container">
<img
src={ImgPath}
onMouseOver={handleOnMouseOver}
alt="logo"
/>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
値の更新
Reactパッケージのメンバ関数useStateで定数に代入した値を変数のように変更することができます。
例えば次のコードをブラウザに出し、Yesの文字をクリックするとNoに代わります。
import React from 'react';
import ReactDOM from 'react-dom/client';
function App () {
const [isImportant,setIsImportant] = React.useState("Yes");
function handleClick() {
setIsImportant("No");
}
return (
<div className="state">
<h1 className="state--title">Is state important to know?</h1>
<div className="state--value" onClick={handleClick}>
<h1>{isImportant}</h1>
</div>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
最初の出力:
Yesの文字をクリックしたときの出力
もう少し複雑なものだと次のように値を増減させるコードも作れます。
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
const [count, setCount] = React.useState(0);
function add() {
setCount(count+1);
};
function subtract() {
setCount(count-1);
};
return (
<div className="counter">
<button className="counter--minus" onClick={subtract}>–</button>
<div className="counter--count">
<h1>{count}</h1>
</div>
<button className="counter--plus" onClick={add}>+</button>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
コールバック関数
コールバック関数(関数が実行されると勝手に実行される関数)を更新の関数に設定して、複雑な更新をすることもできます。
次の例では関数addをコールバック関数で書き直してみました。prevCountに引数が渡されてコールバック関数が実行され、その結果がsetCountに渡されています。
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
const [count, setCount] = React.useState(0);
function add() {
setCount(prevCount => prevCount + 1);
};
function subtract() {
setCount(count-1);
};
return (
<div className="counter">
<button className="counter--minus" onClick={subtract}>–</button>
<div className="counter--count">
<h1>{count}</h1>
</div>
<button className="counter--plus" onClick={add}>+</button>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
配列の要素の追加
ボタン操作で要素を追加してそれを反映させます。
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
//配列とそれを上書きする関数
const [things, setThings] = React.useState(["Thing 1", "Thing 2"]);
function addItem() {
//新しい要素
const newThingText = `Thing ${things.length + 1}`;
//配列の更新
setThings(prevState => [...prevState, newThingText]);
}
//要素をJSXにする
const thingsElements = things.map(thing => <p key={thing}>{thing}</p>);
return (
<div>
<button onClick={addItem}>Add Item</button>
{thingsElements}
</div>
)
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
addItemボタンをクリックすると配列が要素を追加したものに更新されてどんどん表示される要素が増えていきます。
3項演算子を使った切り替え
先ほどのYes/NoではYesをクリックしたらNoになりますが、NoをクリックしてもYesにはなりません。これを解決します。
let var = (条件判定)? (trueの場合): (falseの場合)
とすれば、変数varは条件判定に応じて2種類の値をとります。
今回は条件isGoingOutをReact.useStateで変更しながらその都度、三興演算子で吐き出す値を決めることにします。
import './App.css';
import React from "react"
function App() {
const [isGoingOut,setIsGoing] = React.useState(true);
function changeMind(){
setIsGoing(prevState => !prevState);
};
return (
<div className="state">
<h1 className="state--title">Do I feel like going out tonight?</h1>
<div onClick={changeMind} className="state--value">
<h1>{isGoingOut? "Yes": "No"}</h1>
</div>
</div>
);
}
export default App;
//index.jsはcreate-react-appでできたものをそのまま使っている。
これを実行すると、Yes/Noの文字をクリックする度にYesとNoが切り替わります。
配列と要素の切り替えの組み合わせ
import React from 'react';
function Box(props){
const [on,setOn] = React.useState(props.on);
const styles = {
backgroundColor: on? "#222222" : "transparent"
};
function toggle(){
setOn(prevOn => !prevOn);
};
return (
<div style={styles} className="box" key={props.id} onClick={toggle}></div>
);
};
export default Box;
const boxes = [
{
id: 1,
on: true
},
{
id: 2,
on: false
},
{
id: 3,
on: true
},
{
id: 4,
on: true
},
{
id: 5,
on: false
},
{
id: 6,
on: false
},
];
export default boxes;
import React from 'react';
import './App.css';
import boxes from './boxes';
import Box from './components/Box';
function App(props) {
const [squares, setSquares] = React.useState(boxes);
const squareElements = squares.map(square => (
<Box key={square.id} on={square.on} />
));
return (
<main>
{squareElements}
</main>
);
}
export default App;
出力結果
これを実行すると6つの四角い箱が表示されて、クリックすると白黒が反転します。
初期状態:
左から4番目と6番目の箱をクリック: