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

时间:2017-04-23 13:10:27

标签: javascript reactjs audio

感谢任何帮助,因为我是少年,很难适应其他答案。我正在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')
);

1 个答案:

答案 0 :(得分:0)

将来源传递到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处理程序,将其包装为使用传递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>
        )
    }
});