Javascript “如何制作父级/包装器组件”;“触发”;还是给孩子们打电话?

Javascript “如何制作父级/包装器组件”;“触发”;还是给孩子们打电话?,javascript,reactjs,Javascript,Reactjs,假设我有以下几点: <Group> <Item mediaUrl="http://some/media/file.mp3" /> <Item mediaUrl="http://another/media/file.mp3" /> </Group> 我不明白的是,如何让Group在Item中启动一个方法,而不使用Redux之类的东西?(我试图让这些组件尽可能简单和纯粹)你不能也不应该这样做。但在少数情况下,如设置焦点或触发一些不会真正改变状

假设我有以下几点:

<Group>
  <Item mediaUrl="http://some/media/file.mp3" />
  <Item mediaUrl="http://another/media/file.mp3" />
</Group>

我不明白的是,如何让
Group
Item
中启动一个方法,而不使用Redux之类的东西?(我试图让这些组件尽可能简单和纯粹)

你不能也不应该这样做。但在少数情况下,如设置焦点或触发一些不会真正改变状态的东西,可能需要它。这个问题的关键是DOM还没有创建。这方面有一个例子

render:function(){
返回此项。_input=c}/>;
},
componentDidMount:function(){
这是。_input.focus();
},
所以在这里设置
ref
属性,然后在装载dom之后设置焦点。在其他情况下,我建议使用将属性从父组件传递到子组件来完成所有操作

更多帮助:


    • 你不能也不应该这样做。但在少数情况下,如设置焦点或触发一些不会真正改变状态的东西,可能需要它。这个问题的关键是DOM还没有创建。这方面有一个例子

      render:function(){
      返回此项。_input=c}/>;
      },
      componentDidMount:function(){
      这是。_input.focus();
      },
      
      所以在这里设置
      ref
      属性,然后在装载dom之后设置焦点。在其他情况下,我建议使用将属性从父组件传递到子组件来完成所有操作

      更多帮助:


      想出了一个不涉及黑客或参考的解决方案,我想与大家分享

      My
      Group
      组件具有以下方法:

        componentDidMount() {
          this.setState({
            playlist: React.Children.map(this.props.children, t => t.props.id),
          });
        }
      
        render() {
          if (!this.props.children) {
            console.error('Warning: TrackGroup must contain audio tracks');
            return null;
          }
      
          const tracks = React.Children.map(this.props.children, (child, i) => {
            return React.cloneElement(child, {
              onTrackEnd: this.trackEnded,
              playNext: this.state.playNext,
            });
          });
      
          return <div>{tracks}</div>
        }
      
      componentDidMount(){
      这是我的国家({
      播放列表:React.Children.map(this.props.Children,t=>t.props.id),
      });
      }
      render(){
      如果(!this.props.children){
      console.error('警告:轨迹组必须包含音频轨迹');
      返回null;
      }
      const tracks=React.Children.map(this.props.Children,(child,i)=>{
      返回React.cloneElement(子级{
      onTrackEnd:this.trackEnded,
      playNext:this.state.playNext,
      });
      });
      返回{tracks}
      }
      

      当每个
      项目
      组件将接收道具
      激发时,我检查
      nextrops.playNext
      以查看它是否匹配
      此.props.id
      。如果是,音频会调用this.clickedPlay()(就像用户单击了播放按钮一样)。工作起来很有魅力。

      想出了一个不涉及黑客或参考的解决方案,我想与大家分享

      My
      Group
      组件具有以下方法:

        componentDidMount() {
          this.setState({
            playlist: React.Children.map(this.props.children, t => t.props.id),
          });
        }
      
        render() {
          if (!this.props.children) {
            console.error('Warning: TrackGroup must contain audio tracks');
            return null;
          }
      
          const tracks = React.Children.map(this.props.children, (child, i) => {
            return React.cloneElement(child, {
              onTrackEnd: this.trackEnded,
              playNext: this.state.playNext,
            });
          });
      
          return <div>{tracks}</div>
        }
      
      componentDidMount(){
      这是我的国家({
      播放列表:React.Children.map(this.props.Children,t=>t.props.id),
      });
      }
      render(){
      如果(!this.props.children){
      console.error('警告:轨迹组必须包含音频轨迹');
      返回null;
      }
      const tracks=React.Children.map(this.props.Children,(child,i)=>{
      返回React.cloneElement(子级{
      onTrackEnd:this.trackEnded,
      playNext:this.state.playNext,
      });
      });
      返回{tracks}
      }
      

      当每个
      项目
      组件将接收道具
      激发时,我检查
      nextrops.playNext
      以查看它是否匹配
      此.props.id
      。如果是,音频会调用this.clickedPlay()(就像用户单击了播放按钮一样)。工作起来很有魅力。

      我想你是在尝试播放下一首歌吧?我可能会尝试通过传递另一个道具(可能是布尔值)来解决此问题,该道具确定歌曲是否在渲染时播放。父级将跟踪在其状态中最后播放、正在播放或将要播放的歌曲。当您的歌曲结束事件触发时,父级将调用setState并更新每个状态值,并相应地重新渲染自身及其子级

      组成部分:

      类组扩展了React.Component{
      建造师(道具){
      超级(道具)
      }
      状态={
      //初始状态。小心按下第一首歌曲上的“后退”按钮:p(显然可以改善这一点)
      前任:-1,
      电流:0,
      下一个:1
      }
      handleEnd=()=>{
      //对第一首歌、最后一首歌等执行各种条件检查,并相应地编码。这过于简单,以线性方式进行。您可以将其外推到选择任何歌曲、后退或前进按钮等的其他方法中。
      如果(…){
      这是我的国家({
      上一个:上一个+=1,
      电流:电流+=1,
      下一个:下一个+=1
      });
      }
      }
      渲染(){
      让歌曲=this.props.songs;
      让歌曲列表=歌曲。地图((歌曲)=>{
      if(song.index==this.state.current){
      返回(
      );
      }
      否则{
      返回(
      );
      };
      }
      返回(
      {歌曲列表}
      );
      }
      }
      类项扩展了React.Component{
      建造师(道具){
      超级(道具)
      }
      componentDidMount=()=>{
      如果(this.props.playing==1){
      这个。play();
      };
      }
      播放=()=>{
      //播放url或其他内容中的音乐。
      }
      渲染(){
      //歌曲的一些图形表示。
      }
      }
      
      创建新的播放列表组件:

      someSongs = [...];
      ReactDOM.render(
        <Group songs={someSongs} />,
        document.getElementById('...')
      );
      
      someSongs=[…];
      ReactDOM.render(
      ,
      document.getElementById(“…”)
      );
      
      我假设您正在尝试播放下一首歌曲?我可能会尝试通过传递另一个道具(可能是布尔值)来解决此问题,该道具确定歌曲是否在渲染时播放。父级将跟踪在其状态中播放的最后一首歌曲、正在播放的歌曲或将播放的下一首歌曲。当您的歌曲结束时t激发时,父对象将调用setState并更新每个状态值,并相应地重新呈现自身及其子对象

      组成部分:

      class Group extends React.Component { constructor(props) { super(props) } state = { // Initial state. Be careful pressing the back button on the first song :p (Obviously improve this) previous: -1, current: 0, next: 1 } handleEnd = () => { // Perform all sorts of condition checks for first song, last song, etc. and code accordingly. This is simplistic, proceeding in linear fashion. You can extrapolate this into other methods for selection of any song, back or forward button, etc. if (...) { this.setstate({ previous: previous += 1, current: current += 1, next: next +=1 }); } } render () { let songs = this.props.songs; let songList = songs.map((song) => { if (song.index === this.state.current) { return ( <Item playing=1 onEnd={this.handleEnd} mediaUrl={song.url} /> ); } else { return ( <Item playing=0 onEnd={this.handleEnd} mediaUrl={song.url} /> ); }; } return ( <div> {songList} </div> ); } } class Item extends React.Component { constructor(props) { super(props) } componentDidMount = () => { if (this.props.playing === 1) { this.play(); }; } play = () => { // Play the music from the url or whatever. } render () { <div> // Some graphical representation of song. </div> } }
      someSongs = [...];
      ReactDOM.render(
        <Group songs={someSongs} />,
        document.getElementById('...')
      );