繁体   English   中英

音频播放器(Reactjs):如何在点击时使用子属性更新父状态

[英]Audio player (Reactjs): how to update parent state with a property of child on click

感谢任何帮助,因为我是一名少年,并且难以适应其他答案。 我正在React中创建一个非常基本的双轨音频播放器应用程序。 音频播放器在一个子组件中具有全局播放/暂停控件(当前是html音频元素),并且在兄弟组件中具有2个轨道的轨道列表。

每个轨道都有一个按钮,点击该按钮应播放全局音频元素中的所选音频。 全局音频元素具有默认音频src,它是初始应用程序状态。 我希望此状态更新时单击所选曲目的音频源。

我已设法在父应用程序和每个孩子之间建立通信通道,但我似乎无法将应用程序状态更新为所选轨道的音频src。 我的理解是应用程序中的onTrackChange函数是应该执行此操作的位置。 任何帮助,将不胜感激。

var TRACKLIST = [
    {
        id: 1,
        name: "song a",
        source: "./audio/one.m4a"
    },
    {
        id: 2,
        name: "song b",
        source: "./audio/two.m4a"
    }
]

function Track(props) {
    return (
        <div className="track">
            <div className="meta">
                <div className="name">
                    <h2>{props.name}</h2>
                </div>
                <audio>
                    <source src={props.source} />
                </audio>
            </div>
            <button className="select" onClick={function() {props.onChange();}} >
            </button>
        </div>
    )
}

function Controls(props) {
    return (
        <div className="controls">
            <audio controls>
                <source src={props.source} />
            </audio>
        </div>
    )
}

var Application = React.createClass({

    getInitialState: function() {
        return {
            isPlaying: "./audio/one.m4a"
        };
    },

    onTrackChange: function() {
        // Is it here where the action should take place?
    },

    render: function() {
        return (
            <div className="player">
                <div className="tracklist">
                    {this.props.tracklist.map(function(track){
                        return <Track
                                    key={track.id}
                                    name={track.name}
                                    source={track.source}
                                    onChange={this.onTrackChange} />
                    }.bind(this))}
                </div>
                <Controls source={this.state.isPlaying} />
            </div>
        )
    }
});

// Render the UI
ReactDOM.render(
    <Application tracklist={TRACKLIST} />,
    document.getElementById('Player')
);

将源传递给onChange函数

function Track(props) {
    return (
        <div className="track">
            <div className="meta">
                <div className="name">
                    <h2>{props.name}</h2>
                </div>
                <audio>
                    <source src={props.source} />
                </audio>
            </div>
            <button className="select" onClick={function() {props.onChange(props.source);}} >
            </button>
        </div>
    )
}

然后使用它来设置父级中的状态

var Application = React.createClass({

    getInitialState: function() {
        return {
            isPlaying: "./audio/one.m4a"
        };
    },

    // you may need to `.bind(this)` before calling it (or in the constructor
    onTrackChange: function(source) {
        this.setState({ isPlaying: source })
    },

    render: function() {
        return (
            <div className="player">
                <div className="tracklist">
                    {this.props.tracklist.map(function(track){
                        return <Track
                                    key={track.id}
                                    name={track.name}
                                    source={track.source}
                                    onChange={this.onTrackChange} />
                    }.bind(this))}
                </div>
                <Controls source={this.state.isPlaying} />
            </div>
        )
    }
});

另一种方法

这一个基本相同,但只需要更改一个组件。 而不是直接使用onTrackChange作为onChange处理程序,将其包装为使用pass through track.source

var Application = React.createClass({

    getInitialState: function() {
        return {
            isPlaying: "./audio/one.m4a"
        };
    },

    // you may need to `.bind(this)` before calling it (or in the constructor
    onTrackChange: function(source) {
        this.setState({ isPlaying: source })
    },

    render: function() {
        return (
            <div className="player">
                <div className="tracklist">
                    {this.props.tracklist.map(function(track){
                        return <Track
                                    key={track.id}
                                    name={track.name}
                                    source={track.source}
                                    onChange={function() { this.onTrackChange(track.source);}.bind(this)} />
                    }.bind(this))}
                </div>
                <Controls source={this.state.isPlaying} />
            </div>
        )
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM