<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>⚛️ React todo</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css" /> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: rgb(240, 240, 255); } .tweet { display: flex; background-color: white; } .tweet:not(:last-child){ border-bottom: 1px solid rgb(200, 200, 200); } .icon-container { width: 1.5em; font-size: 3em; padding: 0.2em; } .body-container { flex: 1; padding: 0.5em; } .account-name { color: gray; } </style> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> function Tweet(props){ return ( <div className="tweet"> <div className="icon-container">{props.icon}</div> <div className="body-container"> <div className="status-display"> <div className="display-name">{props.displayName}</div> <div className="account-name">@{props.accountName}</div> </div> <div className="content">{props.content}</div> </div> </div> ) } function App(){ return ( <div> <Tweet icon="👶" displayName="モカ" accountName="mocca" content="まあギャンブルだよね。期待はしてる。" /> <Tweet icon="🦸" displayName="いがこ" accountName="igaco" content="「稼ぐ力」の実態を見極めないと" /> </div> ); } const target = document.getElementById('app'); ReactDOM.render(<App />, target); </script> </body>
– 状態管理
const[value, setValue] = React.useState('defalt'); setValue('new value');
useStateはデフォルト値を与えると、前にコンポーネント関数を呼び出した時の値と、値を更新するための関数を返却
inputできるようにします。
<script type="text/babel"> function Tweet(props){ const[liked, setLike] = React.useState(false); const toggleLike = React.useCallback(() => setLike((prev)=> !prev), [setLike]); return ( <div className="tweet"> <div className="icon-container">{props.icon}</div> <div className="body-container"> <div className="status-display"> <div className="display-name">{props.displayName}</div> <div className="account-name">@{props.accountName}</div> </div> <div className="content">{props.content}</div> <div className="status-action"> <span onClick={toggleLike}>{liked ? '❤️':'♡'}</span> </div> </div> </div> ) } function Timeline(props){ const tweetList = props.tweets.map((tw) => ( <Tweet key={tw.id} icon={tw.icon} displayName={tw.displayName} accountName={tw.accountName} content={tw.content} /> )); return <div className="timeline">{tweetList}</div>; } function TweetInput(props){ const textareaRef = React.useRef(null); const sendTweet = React.useCallback(() => { if(textareaRef.current){ props.addTweet({ id: new Date().getTime(), icon: '☠️', displayName: '龍神', accountName: 'dragon', content: textareaRef.current.value }); } }, [textareaRef.current, props.addTweet]); return ( <div> <div><textarea className="tweet-textarea" ref={textareaRef}></textarea></div> <div><button onClick={sendTweet} className="send-tweet">Tweet</button></div> </div> ); } function App(){ const [tweets, setTweets] = React.useState([ { id: 0, icon: '👶', displayName: 'モカ', accountName: 'mocca', content: 'まあギャンブルだよね。期待はしてる。' }, { id: 1, icon: '🦸', displayName: 'いがこ', accountName: 'igaco', content: '「稼ぐ力」の実態を見極めないと' }, ]); const addTweet = React.useCallback((tweet) => setTweets((prev)=> [tweet, ...prev]), [setTweets]); return ( <div> <TweetInput addTweet={addTweet} /> <Timeline tweets={tweets}/> </div> ); } const target = document.getElementById('app'); ReactDOM.render(<App />, target); </script>
なるほど〜 なんか色々できそうだね