ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,80 @@
+import React from 'react';
+import Comment from './Comment';
+import './CommentList.scss';
+
+class CommentList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      commentInput: '',
+      newComment: [],
+      nickname: '',
+      commentList: [],
+      commentValue: '',
+    };
+  }
+
+  componentDidMount() {
+    fetch('http://localhost:3000/data/commentData.json', {
+      method: 'GET', // GET method는 기본값이라서 생략이 가능합니다.
+    }) // 예시코드에서는 이해를 돕기 위해 명시적으로 기입해뒀습니다.
+      .then(res => res.json())
+      .then(data => {
+        this.setState({
+          commentList: data,
+        });
+      });
+  }
+
+  checkInput = e => {
+    this.setState({
+      commentInput: e.target.value,
+    });
+  };
+
+  inputToComment = () => {
+    const { newComment, commentInput } = this.state;
+    this.setState({
+      nickname: 'wecode_bootcamp',
+      newComment: newComment.concat(commentInput),
+    });
+  };
+
+  enterPress = e => {
+    if (e.key === 'Enter') {
+      this.inputToComment();
+    }
+    e.target.value = '';
+  };
+
+  render() {
+    const { commentValue, commentList } = this.state;
+    return (
+      <div className="commentList">
+        {commentList.map(comment => {
+          return (
+            <Comment
+              key={comment.id}
+              nickname={comment.userName}
+              comment={comment.content}
+            />
+          );
+        })}
+
+        <div className="newText">
+          <input
+            id="typingText"
+            value={commentValue}
+            onChange={this.checkInput}
+            onKeyPress={this.enterPress}
+            type="text"
+            placeholder="댓글 달기...."
+          />
+          <button onClick={this.checkInput}>게시</button>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default CommentList;

리뷰: 비구조화 할당을 적용하면 더 좋을 것 같습니다.
@@ -0,0 +1,23 @@
+import React from 'react';
+import './Comment.scss';
+
+class NewComment extends React.Component {
+  render() {
+    // const newArray = this.props.newComment.map((commentarray, index) => (
+    //   <li key={index}>
+    //     <span className="newCommentid">{this.props.nickname}</span>
+    //     <span className="newComments">{commentarray}</span>
+    //   </li>
+    // ));
+    return (
+      <div className="comment">
+        <div className="newComment">
+          <span className="newCommentid">{this.props.nickname}</span>
+          <span className="newComments">{this.props.comment}</span>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default NewComment;

리뷰: - state 를 사용하지 않는다면, constructor 의 선언이 필요 없습니다!
@@ -0,0 +1,15 @@
+.comment {
+  .newComment {
+    margin-bottom: 5px;
+  }
+
+  .newCommentid {
+    font-weight: bold;
+    margin-bottom: 0;
+  }
+
+  .newComments {
+    font-weight: normal;
+    margin-left: 5px;
+  }
+}

리뷰: - `.comment` 아래로 네스팅 해주세요!
@@ -0,0 +1,80 @@
+import React from 'react';
+import Comment from './Comment';
+import './CommentList.scss';
+
+class CommentList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      commentInput: '',
+      newComment: [],
+      nickname: '',
+      commentList: [],
+      commentValue: '',
+    };
+  }
+
+  componentDidMount() {
+    fetch('http://localhost:3000/data/commentData.json', {
+      method: 'GET', // GET method는 기본값이라서 생략이 가능합니다.
+    }) // 예시코드에서는 이해를 돕기 위해 명시적으로 기입해뒀습니다.
+      .then(res => res.json())
+      .then(data => {
+        this.setState({
+          commentList: data,
+        });
+      });
+  }
+
+  checkInput = e => {
+    this.setState({
+      commentInput: e.target.value,
+    });
+  };
+
+  inputToComment = () => {
+    const { newComment, commentInput } = this.state;
+    this.setState({
+      nickname: 'wecode_bootcamp',
+      newComment: newComment.concat(commentInput),
+    });
+  };
+
+  enterPress = e => {
+    if (e.key === 'Enter') {
+      this.inputToComment();
+    }
+    e.target.value = '';
+  };
+
+  render() {
+    const { commentValue, commentList } = this.state;
+    return (
+      <div className="commentList">
+        {commentList.map(comment => {
+          return (
+            <Comment
+              key={comment.id}
+              nickname={comment.userName}
+              comment={comment.content}
+            />
+          );
+        })}
+
+        <div className="newText">
+          <input
+            id="typingText"
+            value={commentValue}
+            onChange={this.checkInput}
+            onKeyPress={this.enterPress}
+            type="text"
+            placeholder="댓글 달기...."
+          />
+          <button onClick={this.checkInput}>게시</button>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default CommentList;

리뷰: - 구조 분해 할당 해주세요!
```suggestion
  inputToComment = () => {
    const { comment, commentInput } = this.state; 
    this.setState({
      id: 'wecode_bootcamp',
      comment: comment.concat(commentInput),
    });
  };
```
@@ -0,0 +1,23 @@
+import React from 'react';
+import './Comment.scss';
+
+class NewComment extends React.Component {
+  render() {
+    // const newArray = this.props.newComment.map((commentarray, index) => (
+    //   <li key={index}>
+    //     <span className="newCommentid">{this.props.nickname}</span>
+    //     <span className="newComments">{commentarray}</span>
+    //   </li>
+    // ));
+    return (
+      <div className="comment">
+        <div className="newComment">
+          <span className="newCommentid">{this.props.nickname}</span>
+          <span className="newComments">{this.props.comment}</span>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default NewComment;

리뷰: - 컴포넌트와 동일하게 클래스네임 지어주시고, 첫글자를 대문자로 작성하는 컨벤션은 컴포넌트를 네이밍 하기 위한 컨벤션 입니다!
```suggestion
      <div className="comment">
```
@@ -0,0 +1,80 @@
+import React from 'react';
+import Comment from './Comment';
+import './CommentList.scss';
+
+class CommentList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      commentInput: '',
+      newComment: [],
+      nickname: '',
+      commentList: [],
+      commentValue: '',
+    };
+  }
+
+  componentDidMount() {
+    fetch('http://localhost:3000/data/commentData.json', {
+      method: 'GET', // GET method는 기본값이라서 생략이 가능합니다.
+    }) // 예시코드에서는 이해를 돕기 위해 명시적으로 기입해뒀습니다.
+      .then(res => res.json())
+      .then(data => {
+        this.setState({
+          commentList: data,
+        });
+      });
+  }
+
+  checkInput = e => {
+    this.setState({
+      commentInput: e.target.value,
+    });
+  };
+
+  inputToComment = () => {
+    const { newComment, commentInput } = this.state;
+    this.setState({
+      nickname: 'wecode_bootcamp',
+      newComment: newComment.concat(commentInput),
+    });
+  };
+
+  enterPress = e => {
+    if (e.key === 'Enter') {
+      this.inputToComment();
+    }
+    e.target.value = '';
+  };
+
+  render() {
+    const { commentValue, commentList } = this.state;
+    return (
+      <div className="commentList">
+        {commentList.map(comment => {
+          return (
+            <Comment
+              key={comment.id}
+              nickname={comment.userName}
+              comment={comment.content}
+            />
+          );
+        })}
+
+        <div className="newText">
+          <input
+            id="typingText"
+            value={commentValue}
+            onChange={this.checkInput}
+            onKeyPress={this.enterPress}
+            type="text"
+            placeholder="댓글 달기...."
+          />
+          <button onClick={this.checkInput}>게시</button>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default CommentList;

리뷰: - id 라는 값은 무슨 용도를 위해 작성해 주신 걸까요? id 는 꼭 필요한 부분이 아니라면 사용을 지양해주세요! id 값은 프로젝트 내에서 유일해야 합니다. 
- id 를 사용하는 경우는 예를 들어, google map api 를 사용해서 지도를 그릴때, 지도를 그릴 html element 를 특정할 때 사용되곤 합니다.
@@ -0,0 +1,80 @@
+import React from 'react';
+import Comment from './Comment';
+import './CommentList.scss';
+
+class CommentList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      commentInput: '',
+      newComment: [],
+      nickname: '',
+      commentList: [],
+      commentValue: '',
+    };
+  }
+
+  componentDidMount() {
+    fetch('http://localhost:3000/data/commentData.json', {
+      method: 'GET', // GET method는 기본값이라서 생략이 가능합니다.
+    }) // 예시코드에서는 이해를 돕기 위해 명시적으로 기입해뒀습니다.
+      .then(res => res.json())
+      .then(data => {
+        this.setState({
+          commentList: data,
+        });
+      });
+  }
+
+  checkInput = e => {
+    this.setState({
+      commentInput: e.target.value,
+    });
+  };
+
+  inputToComment = () => {
+    const { newComment, commentInput } = this.state;
+    this.setState({
+      nickname: 'wecode_bootcamp',
+      newComment: newComment.concat(commentInput),
+    });
+  };
+
+  enterPress = e => {
+    if (e.key === 'Enter') {
+      this.inputToComment();
+    }
+    e.target.value = '';
+  };
+
+  render() {
+    const { commentValue, commentList } = this.state;
+    return (
+      <div className="commentList">
+        {commentList.map(comment => {
+          return (
+            <Comment
+              key={comment.id}
+              nickname={comment.userName}
+              comment={comment.content}
+            />
+          );
+        })}
+
+        <div className="newText">
+          <input
+            id="typingText"
+            value={commentValue}
+            onChange={this.checkInput}
+            onKeyPress={this.enterPress}
+            type="text"
+            placeholder="댓글 달기...."
+          />
+          <button onClick={this.checkInput}>게시</button>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default CommentList;

리뷰: - 여기도 id 를 사용하지 않는데 불필요하게 사용하는 것 같습니다! 지워주세요~
@@ -1,13 +1,92 @@
 import React from 'react';
+import { withRouter } from 'react-router-dom';
+import './Login.scss';
 
 class LoginAh extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      idInput: '',
+      pwInput: '',
+    };
+  }
+
+  loginTest = () => {
+    fetch('users/login', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({
+        email: this.state.idInput,
+        password: this.state.pwInput,
+      }),
+    })
+      .then(response => response.json())
+      .then(response => {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+          this.props.history.push('/MainAh');
+        } else {
+          alert('아이디/비밀번호가 틀렸습니다!');
+        }
+      });
+  };
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/MainAh');
+  };
+
   render() {
+    const { idInput, pwInput } = this.state;
+    const isButtonActive = idInput.includes('@') && pwInput.length >= 5;
     return (
-      <div>
-        <p>다슬</p>
+      <div className="Login">
+        <div className="container">
+          <div className="loginContainer">
+            <p>westagram</p>
+            <div className="idContainer">
+              <input
+                onChange={this.handleInput}
+                name="idInput"
+                type="text"
+                className="inputId"
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+            </div>
+            <div className="passwordContainer">
+              <input
+                onChange={this.handleInput}
+                name="pwInput"
+                type="password"
+                className="inputPassword"
+                placeholder="비밀번호"
+              />
+            </div>
+            <button
+              disabled={!isButtonActive}
+              className={`loginButton ${
+                isButtonActive ? 'loginButtonOn' : 'loginButtonOff'
+              }`}
+              // onClick={this.goToMain}
+              onClick={this.loginTest}
+            >
+              로그인
+            </button>
+            <div>
+              <a href="google.com">비밀번호를 잊으셨나요?</a>
+            </div>
+          </div>
+        </div>
       </div>
     );
   }
 }
 
-export default LoginAh;
+export default withRouter(LoginAh);

리뷰: - constructor 선언을 가장 위에 위치시켜주세요!
@@ -1,13 +1,92 @@
 import React from 'react';
+import { withRouter } from 'react-router-dom';
+import './Login.scss';
 
 class LoginAh extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      idInput: '',
+      pwInput: '',
+    };
+  }
+
+  loginTest = () => {
+    fetch('users/login', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({
+        email: this.state.idInput,
+        password: this.state.pwInput,
+      }),
+    })
+      .then(response => response.json())
+      .then(response => {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+          this.props.history.push('/MainAh');
+        } else {
+          alert('아이디/비밀번호가 틀렸습니다!');
+        }
+      });
+  };
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/MainAh');
+  };
+
   render() {
+    const { idInput, pwInput } = this.state;
+    const isButtonActive = idInput.includes('@') && pwInput.length >= 5;
     return (
-      <div>
-        <p>다슬</p>
+      <div className="Login">
+        <div className="container">
+          <div className="loginContainer">
+            <p>westagram</p>
+            <div className="idContainer">
+              <input
+                onChange={this.handleInput}
+                name="idInput"
+                type="text"
+                className="inputId"
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+            </div>
+            <div className="passwordContainer">
+              <input
+                onChange={this.handleInput}
+                name="pwInput"
+                type="password"
+                className="inputPassword"
+                placeholder="비밀번호"
+              />
+            </div>
+            <button
+              disabled={!isButtonActive}
+              className={`loginButton ${
+                isButtonActive ? 'loginButtonOn' : 'loginButtonOff'
+              }`}
+              // onClick={this.goToMain}
+              onClick={this.loginTest}
+            >
+              로그인
+            </button>
+            <div>
+              <a href="google.com">비밀번호를 잊으셨나요?</a>
+            </div>
+          </div>
+        </div>
       </div>
     );
   }
 }
 
-export default LoginAh;
+export default withRouter(LoginAh);

리뷰: - defaultColor 와 disabled 는 state 로 관리하기에는 부적절한 값 같습니다. idInput 과 pwInput 를 사용해서 계산할 수 있는 값이기 때문입니다!
- 어떤 기준으로 state 를 만들어야 하는지에 대해서는 아래 문서를 참고해주세요!
- https://ko.reactjs.org/docs/thinking-in-react.html#step-3-identify-the-minimal-but-complete-representation-of-ui-state
- state 로 관리할 필요가 없는 값들은 state 를 만들지 않도록 해주세요. 값을 수정하기 위해선, setState 를 사용해야하고, 이는 일어나지 않아도 되는 불필요한 렌더링을 발생시키기 때문입니다.
@@ -1,13 +1,92 @@
 import React from 'react';
+import { withRouter } from 'react-router-dom';
+import './Login.scss';
 
 class LoginAh extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      idInput: '',
+      pwInput: '',
+    };
+  }
+
+  loginTest = () => {
+    fetch('users/login', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({
+        email: this.state.idInput,
+        password: this.state.pwInput,
+      }),
+    })
+      .then(response => response.json())
+      .then(response => {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+          this.props.history.push('/MainAh');
+        } else {
+          alert('아이디/비밀번호가 틀렸습니다!');
+        }
+      });
+  };
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/MainAh');
+  };
+
   render() {
+    const { idInput, pwInput } = this.state;
+    const isButtonActive = idInput.includes('@') && pwInput.length >= 5;
     return (
-      <div>
-        <p>다슬</p>
+      <div className="Login">
+        <div className="container">
+          <div className="loginContainer">
+            <p>westagram</p>
+            <div className="idContainer">
+              <input
+                onChange={this.handleInput}
+                name="idInput"
+                type="text"
+                className="inputId"
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+            </div>
+            <div className="passwordContainer">
+              <input
+                onChange={this.handleInput}
+                name="pwInput"
+                type="password"
+                className="inputPassword"
+                placeholder="비밀번호"
+              />
+            </div>
+            <button
+              disabled={!isButtonActive}
+              className={`loginButton ${
+                isButtonActive ? 'loginButtonOn' : 'loginButtonOff'
+              }`}
+              // onClick={this.goToMain}
+              onClick={this.loginTest}
+            >
+              로그인
+            </button>
+            <div>
+              <a href="google.com">비밀번호를 잊으셨나요?</a>
+            </div>
+          </div>
+        </div>
       </div>
     );
   }
 }
 
-export default LoginAh;
+export default withRouter(LoginAh);

리뷰: - 구조 분해 할당 활용해 주시면 더 좋을 것 같습니다!
```suggestion
    const { name, value } = event.target;
    this.setState({
      [name]: value,
    });
```
@@ -1,13 +1,92 @@
 import React from 'react';
+import { withRouter } from 'react-router-dom';
+import './Login.scss';
 
 class LoginAh extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      idInput: '',
+      pwInput: '',
+    };
+  }
+
+  loginTest = () => {
+    fetch('users/login', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({
+        email: this.state.idInput,
+        password: this.state.pwInput,
+      }),
+    })
+      .then(response => response.json())
+      .then(response => {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+          this.props.history.push('/MainAh');
+        } else {
+          alert('아이디/비밀번호가 틀렸습니다!');
+        }
+      });
+  };
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/MainAh');
+  };
+
   render() {
+    const { idInput, pwInput } = this.state;
+    const isButtonActive = idInput.includes('@') && pwInput.length >= 5;
     return (
-      <div>
-        <p>다슬</p>
+      <div className="Login">
+        <div className="container">
+          <div className="loginContainer">
+            <p>westagram</p>
+            <div className="idContainer">
+              <input
+                onChange={this.handleInput}
+                name="idInput"
+                type="text"
+                className="inputId"
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+            </div>
+            <div className="passwordContainer">
+              <input
+                onChange={this.handleInput}
+                name="pwInput"
+                type="password"
+                className="inputPassword"
+                placeholder="비밀번호"
+              />
+            </div>
+            <button
+              disabled={!isButtonActive}
+              className={`loginButton ${
+                isButtonActive ? 'loginButtonOn' : 'loginButtonOff'
+              }`}
+              // onClick={this.goToMain}
+              onClick={this.loginTest}
+            >
+              로그인
+            </button>
+            <div>
+              <a href="google.com">비밀번호를 잊으셨나요?</a>
+            </div>
+          </div>
+        </div>
       </div>
     );
   }
 }
 
-export default LoginAh;
+export default withRouter(LoginAh);

리뷰: - defaultColor 와 disabled 를 state 에서 관리하지 않도록 한다면, 이 로직 부분은 더 이상 필요 없을 것 같습니다.
@@ -1,13 +1,92 @@
 import React from 'react';
+import { withRouter } from 'react-router-dom';
+import './Login.scss';
 
 class LoginAh extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      idInput: '',
+      pwInput: '',
+    };
+  }
+
+  loginTest = () => {
+    fetch('users/login', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({
+        email: this.state.idInput,
+        password: this.state.pwInput,
+      }),
+    })
+      .then(response => response.json())
+      .then(response => {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+          this.props.history.push('/MainAh');
+        } else {
+          alert('아이디/비밀번호가 틀렸습니다!');
+        }
+      });
+  };
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/MainAh');
+  };
+
   render() {
+    const { idInput, pwInput } = this.state;
+    const isButtonActive = idInput.includes('@') && pwInput.length >= 5;
     return (
-      <div>
-        <p>다슬</p>
+      <div className="Login">
+        <div className="container">
+          <div className="loginContainer">
+            <p>westagram</p>
+            <div className="idContainer">
+              <input
+                onChange={this.handleInput}
+                name="idInput"
+                type="text"
+                className="inputId"
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+            </div>
+            <div className="passwordContainer">
+              <input
+                onChange={this.handleInput}
+                name="pwInput"
+                type="password"
+                className="inputPassword"
+                placeholder="비밀번호"
+              />
+            </div>
+            <button
+              disabled={!isButtonActive}
+              className={`loginButton ${
+                isButtonActive ? 'loginButtonOn' : 'loginButtonOff'
+              }`}
+              // onClick={this.goToMain}
+              onClick={this.loginTest}
+            >
+              로그인
+            </button>
+            <div>
+              <a href="google.com">비밀번호를 잊으셨나요?</a>
+            </div>
+          </div>
+        </div>
       </div>
     );
   }
 }
 
-export default LoginAh;
+export default withRouter(LoginAh);

리뷰: - idInput 과 pwInput 을 사용해서 바로 값을 계산할 수 있습니다. 코드는 다음과 같습니다. 참고해주세요!
- inline 스타일링을 주시는 것은 꼭 필요한 경우가 아니라면 지양해주시고, className 을 동적으로 부여하는 것으로 스타일링 해주세요!
- inline 스타일링을 사용하시는 경우는, 슬라이더를 구현과 같이 스타일링이 매우 많이 지속적으로 변해야 하는 상황에 사용해 주시는 겁니다!
```jsx
render () {
  const { idInput, pwInput } = this.state;
  isButtonActive =  idInput.includes('@') && pwInput.length >= 5
  return (
    ...
    <button 
      disabled={!isButtonActive}
      className={`loginButton ${isButtonActive ? 'active' : ''}`}
      onClick={this.goToMain}
    >
    ...
  )
}
```