Asked Aug 20th, 2018 8:04 a.m. 134 0 2
  • 134 0 2
+1

Tại sao khi click lần đầu tiên hành động chưa thực thi ngay

Share
  • 134 0 2

Mình đang tìm hiểu về ReactJs, mọi người cho mình hỏi tại sao đoạn code thực hiện chức năng Accordion dưới đây viết bằng ReactJs, khi load vào trang mình click lần đầu tiên thì sự kiện nó chưa kích hoạt ngay mà phải đến lần thứ 2 nó mới bắt sự kiện nhỉ:

https://codepen.io/anon/pen/NLKVrR?editors=1010

Mình cám ơn mọi nguwoif !

2 ANSWERS


Answered Aug 20th, 2018 8:12 a.m.
Accepted
+4

Theo code hiện tại của bạn thì sau khi bạn click lần đầu tiên thì nó mới tiến hành gán sự kiện này vào thẻ div

itemAccor.onclick = () => itemAccor.classList.toggle("active");

Nếu bạn muốn nó chạy ngay lần đâu tiên thì nên khai báo phần gán function này ở trong hàm componentDidMount() luôn như này:

class Accordion extends React.Component {
    
  componentDidMount() {
    const myAccor = this.getEle.children;
    console.log(myAccor);
    for (let i = 0; i < myAccor.length; i++) {
      console.log(myAccor[i]);
      let itemAccor = myAccor[i];
      itemAccor.onclick = () => itemAccor.classList.toggle("active");
    }
  }
  
  render() {
    return (
      <div
        ref={ele => this.getEle = ele} 
        onClick={this.handleClick}>
        {this.props.children}
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
  
        <Accordion>
        
          <div className="accor">
            <div className="head">Head 1</div>
            <div className="body">
              Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            </div>
          </div>
        
          <div className="accor">
            <div className="head">Head 2</div>
            <div className="body">
              Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            </div>
          </div>
        
        </Accordion>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
Share
Aug 20th, 2018 8:27 a.m.

Bạn có thể cập nhât lại code như này sẽ tối ưu hơn tí 😄 https://codepen.io/anon/pen/NLKVwp?editors=1010

+1
| Reply
Share
Avatar Hoang vn @wiliamfeng
Aug 20th, 2018 8:49 a.m.

@HuyDQ tks bạn nhé, code của bạn về logic dễ hiểu hơn rất nhiều

+1
| Reply
Share
Answered Aug 20th, 2018 8:15 a.m.
+3

Bởi vì trong lần đầu tiên load, sau khi click vào thẻ div thì mới gán sự kiện onClick cho component Accor.

Share
Avatar Hoang vn @wiliamfeng
Aug 20th, 2018 8:21 a.m.

LÀ như nào hả các bạn ? Mình chưa thực sự rõ lắm , các bạn có thể giải thích cho mình cặn kẽ hơn chút có đc không ? Mình thì hiểu thế này :

Thằng cha được khai báo sự kiện : onClick={this.handleClick} => khi click vô nó => nó sẽ gọi đến hàm handleClick => hàm này có chức năng duyệt qua các con nằm trong thằng cha => nếu phát hiện sự kiện click vừa rồi ứng với thằng con nào : itemAccor.onclick = () => itemAccor.classList.toggle("active") =,> sẽ toogle class cho thằng con đó.

Logic chẳng phải như vậy sao ?

0
| Reply
Share
Aug 20th, 2018 8:37 a.m.

@wiliamfeng hàm handleClick của bạn thực chất nó có nhiệm vụ gán cái sự kiện itemAccor.onclick = () => itemAccor.classList.toggle("active") cho thẻ div. Sau lần click đầu tiên thì các thẻ div đã được gán sự kiện rồi nó mới chạy được cái toggle bạn khai báo

+2
| Reply
Share
Avatar Hoang vn @wiliamfeng
Aug 20th, 2018 8:43 a.m.

@HuyDQ tks bạn

0
| Reply
Share
Aug 20th, 2018 8:44 a.m.

@wiliamfeng ok bạn 😄

0
| Reply
Share
Viblo
Let's register a Viblo Account to get more interesting posts.