質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

412閲覧

「react.js」子コンポーネントに渡す値をまとめられないか??

kazoogon

総合スコア281

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/08/21 08:51

編集2018/08/22 09:04

今していること

react.jsを使用しリアルタイムでバリデーションチェックする登録画面を作っております
イメージ説明

問題点

パスワードの値をチェックする際に3つ条件を見る
→そこでの子コンポーネントに渡す値をまとめることはできないのか? と疑問に

コード(コード内に質問は書きました)

function PasswordBallon(props){ return ( <div className="passwordBallon">{props.NumberOfPassword} <ul> <span className="title">Password rules</span> <li>//**①以下の条件分岐を短くできないか? {(() => { if(props.NumberOfPassword == true){ return <img src="../img/check-solid.svg" style={{height:"22px"}}/>  }else{ return <img src="../img/baseline-error_outline-24px.svg" />  } })()} {(() => { if(props.NumberOfPassword == true){ return <span style={{color:"#E4E7E8"}}>&nbsp;8 characters minimum</span>  }else{ return <span>&nbsp;8 characters minimum</span>  } })()} </li> <li> {(() => { if(props.CheckNumber == true){ return <img src="../img/check-solid.svg" style={{height:"22px"}}/>  }else{ return <img src="../img/baseline-error_outline-24px.svg" />  } })()} {(() => { if(props.CheckNumber == true){ return <span style={{color:"#E4E7E8"}}>&nbsp;Contains at least 1 number</span>  }else{ return <span>&nbsp;Contains at least 1 number</span>  } })()} </li> <li> {(() => { if(props.CheckCharacter == true){ return <img src="../icon/check-solid.svg" style={{height:"22px"}}/>  }else{ return <img src="../icon/baseline-error_outline-24px.svg" />  } })()} {(() => { if(props.CheckCharacter == true){ return <span style={{color:"#E4E7E8"}}>&nbsp;Can't be "password", "username"</span>  }else{ return <span>&nbsp;Can't be "password", "username"</span>  } })()} </li> </ul> </div> ); } class App extends React.Component { constructor() { super(); this.state = { display: false, fields: {}, errors: {}, NumberOfPassword: false, CheckNumber: false, CheckCharacter: false, }; this.passwordClick = this.passwordClick.bind(this); } passwordClick() { this.setState({ display: true }); } handleChange(field, e){ let errors = {}; let fields = this.state.fields; fields[field] = e.target.value; this.setState({fields}); if(!fields["password"]){ // formIsValid = false; errors["EmptyPassword"] = "Cannot be empty"; } if(typeof fields["password"] !== "undefined"){ if(fields["password"].match(/^.{8,}$/)){ // formIsValid = false; this.setState({NumberOfPassword: true}); }else{ this.setState({NumberOfPassword: false}); } if(fields["password"].match(/[0-9]/)){ // formIsValid = false; this.setState({CheckNumber: true}); }else{ this.setState({CheckNumber: false}); } if(fields["password"] != ("password" || "user")){ this.setState({CheckCharacter: true}); }else{ this.setState({CheckCharacter: false}); } } } ////component名は最初大文字な** render(){ return( <div className='signup'> <h1>Create Account</h1> <div><input type="text" name="name" placeholder="name"/></div> <div><input type="text" name="email" placeholder="email"/></div> <div className="wrapperPassword"> <input type="password" name="password" placeholder="password" onClick={this.passwordClick} onChange={this.handleChange.bind(this, "password")} value={this.state.fields["password"]} /> { this.state.display ? <PasswordBallon //**②ここのpasswordの条件をチェックするstateをまとめられないか?? NumberOfPassword = {this.state.NumberOfPassword} CheckNumber = {this.state.CheckNumber} CheckCharacter = {this.state.CheckCharacter} />: null } </div> <div><input type="text" name="passConfirm" placeholder="confirm password"/></div> </div> ); } } ReactDOM.render( <App/>, document.getElementById('wrapper') ); })();

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://codesandbox.io/s/k04v88ljpv

javascript

1import React from "react"; 2import ReactDOM from "react-dom"; 3 4/** 5 * @param {Object} props 6 * @param {boolean} props.isValid 7 * @param {string} props.text 8 * @return {JSX.Element} 9 */ 10const ValidationResultList = ({ isValid, text }) => { 11 const imgStyle = isValid ? { height: "22px" } : {}; 12 const imgSrc = isValid 13 ? "../img/check-solid.svg" 14 : "../img/baseline-error_outline-24px.svg"; 15 const spanStyle = isValid ? { color: "#E4E7E8" } : {}; 16 17 return ( 18 <li> 19 <img style={imgStyle} src={imgSrc} /> 20 <span style={spanStyle}>{text}</span> 21 </li> 22 ); 23}; 24 25/** 26 * @param {Object} props 27 * @param {boolean} props.invalidLength 28 * @param {boolean} props.notContainNumber 29 * @param {boolean} props.blacklistedWord 30 * @return {JSX.Element} 31 */ 32const PasswordBallon = ({ 33 invalidLength, 34 notContainNumber, 35 blacklistedWord 36}) => { 37 return ( 38 <div className="passwordBallon"> 39 <ul> 40 <span className="title">Password rules</span> 41 <ValidationResultList 42 isValid={!invalidLength} 43 text={"&nbsp;8 characters minimum"} 44 /> 45 <ValidationResultList 46 isValid={!notContainNumber} 47 text={"&nbsp;Contains at least 1 number"} 48 /> 49 <ValidationResultList 50 isValid={!blacklistedWord} 51 text={'&nbsp;Can\'t be "password", "username"'} 52 /> 53 </ul> 54 </div> 55 ); 56}; 57 58class App extends React.Component { 59 constructor() { 60 super(); 61 this.state = { 62 name: { 63 value: "", 64 isDirty: false, 65 error: null 66 }, 67 email: { 68 value: "", 69 isDirty: false, 70 error: null 71 }, 72 password: { 73 value: "", 74 isDirty: false, 75 error: { 76 invalidLength: false, 77 notContainNumber: false, 78 blacklistedWord: false 79 } 80 }, 81 passwordConfirm: { 82 value: "", 83 isDirty: false, 84 error: null 85 } 86 }; 87 88 this.onChangePassword = this.onChangePassword.bind(this); 89 } 90 91 // バリデーションはクラス外に切り出してしまった方がいいかな 92 onChangePassword(event) { 93 const currentValue = event.target.value; 94 let invalidLength = false; 95 let notContainNumber = false; 96 let blacklistedWord = false; 97 98 if (typeof currentValue !== "string" || currentValue.length < 1) { 99 invalidLength = true; 100 } else { 101 invalidLength = !currentValue.match(/^.{8,}$/); 102 notContainNumber = !currentValue.match(/[0-9]/); 103 blacklistedWord = ["password", "user"].includes(currentValue); 104 } 105 106 this.setState({ 107 password: { 108 value: currentValue, 109 isDirty: true, 110 error: { 111 invalidLength, 112 notContainNumber, 113 blacklistedWord 114 } 115 } 116 }); 117 } 118 119 showPasswordBaloon() { 120 const { isDirty, error } = this.state.password; 121 if (!isDirty) return false; 122 return true; 123 /* 全部OKならバルーンを消すようにするなら 124 for (let v of Object.values(error)) { 125 if (v) return true; 126 } 127 return false 128 */ 129 } 130 131 render() { 132 return ( 133 <div className="signup"> 134 <h1>Create Account</h1> 135 <div> 136 <input type="text" name="name" placeholder="name" /> 137 </div> 138 <div> 139 <input type="text" name="email" placeholder="email" /> 140 </div> 141 <div className="wrapperPassword"> 142 <input 143 type="password" 144 name="password" 145 placeholder="password" 146 onChange={this.onChangePassword} 147 value={this.state.password.value} 148 /> 149 {this.showPasswordBaloon() ? ( 150 <PasswordBallon {...this.state.password.error} /> 151 ) : ( 152 "" 153 )} 154 </div> 155 <div> 156 <input 157 type="text" 158 name="passConfirm" 159 placeholder="confirm password" 160 /> 161 </div> 162 </div> 163 ); 164 } 165} 166 167ReactDOM.render(<App />, document.getElementById("root"));

投稿2018/08/22 13:10

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazoogon

2018/08/22 22:10

回答ありがとうございます。 こちらのコードとても参考になりました! またsubmitをボタンを作成し、全てのinputの条件を満たしていた場合にsubmitのdisabled属性をfalseにしようと思うのですが、その場合isDirtyの値が全てfalseの場合にしようと思うのですが、他にうまいやり方がもしあれば教えていただきたいです。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2018/08/24 01:13

isDirtyは"編集されているか否か"のフラグなので、それだけで判定するとだめです。https://codesandbox.io/s/7yxq5wooyq こんな感じかな。
kazoogon

2018/08/24 01:51

https://codesandbox.io/s/3roj9wl29m こんな感じになりました。<FormButton>コンポネントから渡す値をまとめてないとか、まだ何かコードに関して指摘いただけるとありがたいです。。
退会済みユーザー

退会済みユーザー

2018/08/24 02:47

ごく短時間ざっと見ただけですが # ソースコードについて 24: const imgSrc = isValid ? ( imgSrcはJSX.Elementなので、これをimgタグのsrcアトリビュートに与えることはできません classNameを切り替えればいいので、isValidに応じてclassを切り替えるようにしましょう 90: this.state = { それぞれのフィールドにerrorとstatusがあって、同じ意味の情報(validか否か)を異なる二つの変数で管理してしまっている。statusという命名も非常に広い意味なので避けたほうがいい。 127: onChange(event) { onChangeを全フィールで共通化しているが、早すぎる無駄な最適化だと思う。 メソッドの肥大化とメンテナンス性の低下を招くと思う。 私ならformikやrecompose等を使うことでこういうボイラーテンプレートを削減します。(現状の理解度では混乱すると思うので、利用することは決してお勧めしません) 318: disabled={ 必ず関数化したほうがいいです # その他 - reactというよりも、プログラミング自体の経験不足を感じます。プログラムの設計を監督・レビューしてくれる人を探したほうがいいです。 - Reactでのテスト方法を学習したほうがいいです、このままでは必ずメンテナンス不能になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問