Невозможно добавить функцию обратного вызова непосредственно в событие click дочернего элемента JSX - PullRequest
0 голосов
/ 04 июня 2018

В настоящее время я пытаюсь создать клон YouTube.Я пытаюсь манипулировать состояниями с помощью функций обратного вызова, передаваемых из родительского компонента в дочерние компоненты.Но проблема в том, что я не могу назначить мою функцию обратного вызова непосредственно событию click моего дочернего компонента JSX.

Я передаю функцию обратного вызова из родительского компонента, APP дочернему компоненту, VideoList и затем сновав VideoListItem.Проблемы есть в VideoListItem.Если я добавляю функцию обратного вызова из приложения непосредственно в JSX, как это onClick={onVideoSelect(video)}, это вызывает бесконечный цикл и выдает сообщение об ошибке «Uncaught Error: превышена максимальная глубина обновления. Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничиваетколичество вложенных обновлений для предотвращения бесконечных циклов. ".

Но если я добавлю функцию обратного вызова, подобную этой onClick={()=> onVideoSelect(video)}, это сработает.Я хочу понять, почему эта ошибка происходит и лежит в основе концепции.

Вот мой index.js

import React ,{Component} from 'react';
import ReactDOM from 'react-dom';
import SearchBar from './components/search_bar';
import YTSearch from 'youtube-api-search';
import VideoList from './components/video_list';
import VideoDetail from './components/video_detail';
// create a new component.That should produce some html

const API_KEY = 'AIzaSyBem7NlPNdK50NStTS4MJDlXBaiRDfI1U0'



class App extends Component  {

    constructor(props){
        super(props);

        this.state = { 
            videos:[],
            selectedVideo: null
        }
        YTSearch(
            { key:API_KEY , term:'spaceart'},
            videos => {
                console.log("Videos Download ::"+videos.length)

                this.setState({
                    videos:videos,
                    selectedVideo:videos[0]
                })
            }
        );
    }

    render() {
    return(
            <div>
            <SearchBar/>
            <VideoDetail video={this.state.selectedVideo} />
            <VideoList onVideoSelect = { selectedVideo => this.setState({selectedVideo}) } videos={this.state.videos} />
            </div>
        );
    }


}
ReactDOM.render(<App/>,document.querySelector('.container'));

video_list.js

    import React from 'react';
import VideoListItem from './video_list_item';

const VideoList = (props)=>{

    const videoComponents = props.videos.map(
        (video) => {
            return <VideoListItem onVideoSelect={props.onVideoSelect} key={video.etag} video={video} />
        }
    )

return (
    <div><ul className="col-md-4 list-group">
    {videoComponents}
    </ul></div>
    );
}

export default VideoList;

video_list_item.js

   import React from 'react';

    const VideoListItem = ({video,onVideoSelect}) => {

        console.log("Enter video list Item");

        return (
            <li onClick={onVideoSelect(video)} className="list-group-item">
                <div cl

 1. List item

assName="video-list media">
                <div className="media-left">
                <img className="media-object" src={video.snippet.thumbnails.default.url } />
           </div>
           <div className="media-body">
                <div className="media-heading">{video.snippet.title} </div>
                </div>
            </div> 
           </li> 
            );
    }

    export default VideoListItem;

1 Ответ

0 голосов
/ 04 июня 2018

Когда вы добавляете скобку () в функцию, она выполняется.Таким образом, эта строка

onClick={onVideoSelect(video)}

заставляет функцию выполняться, как только эта строка встречается.Внутри этой функции вы вызываете setState, поэтому состояние обновляет и запускает метод рендеринга, который затем снова выполняет ваш метод onVideoSelect и формирует цикл.Вам нужно перейти на onClick, ссылку на функцию.Когда происходит событие click, onClick выполняет функцию, которую вы передали ему.

onClick={() => onVideoSelect(video)}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...