ReactJS - 从另一个组件调用组件方法?

时间:2018-03-05 20:10:41

标签: reactjs

是否可以在另一个组件上调用方法?

我已经创建了需要在点击或特定事件发生时切换的内容。

例如,我创建了一个React组件,用作媒体播放器上的播放按钮。我使用LottieJS和bodymovin为SVG按钮设置动画。如果正在播放歌曲,则按钮会显示暂停符号。如果歌曲停止,则显示播放符号。

这是我的PlayButton组件......

import React from 'react';
import Lottie from 'react-lottie';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import * as animationData from './button.json';

const Button = styled.button`
    cursor: pointer;
    outline: none;
    border: none;
    background: none;
    display: block;
    float: left;
    width: 10%;
    margin-top: 27px;
`;

export default class PlayButton extends React.Component {
    static propTypes = {
        onClick: PropTypes.func.isRequired,
    }

    static defaultProps = {
        onClick: () => {}
    }

    state = {
        isStopped: true,
        direction: 1,
        speed: 3,
    }

    toggle = () => {
        const {isStopped, direction} = this.state;
        if (!isStopped) {
          this.setState({direction: direction * -1})
        }
        this.setState({isStopped: false});
        this.props.onclick();
    }

    render() {
        const defaultOptions = {
            loop: false,
            autoplay: false, 
            animationData: animationData,
            rendererSettings: {
                preserveAspectRatio: 'xMidYMid slice',
            },
        };

        return (
            <Button onClick={this.toggle}>
                <Lottie 
                    options={defaultOptions}
                    isStopped={this.state.isStopped}
                    speed={this.state.speed}
                    direction={this.state.direction}
                />
            </Button>
        )
    }
}

我这样渲染:

<PlayButton onclick={this.playButtonClicked} />

单击该按钮时,将使用LottieJS切换SVG动画。

我需要拨打toggle,以便当曲目到达结尾时,播放按钮将从播放切换到停止。这有可能吗?

通常情况下,如果我使用非动画SVG,我就不会遇到这个问题。我会根据状态显示一个CSS background-image。但因为这是一个切换动画,我不知道该怎么做。

3 个答案:

答案 0 :(得分:0)

假设您的函数位于父组件中,您可以将其作为props中的函数传递。

&#13;
&#13;
class Parent extends React.Component {
  parentAlert = () => {
    alert('function from parent')
  }
  
  render() {
    return (
      <div>
        <Child parentAlert={this.parentAlert}/>
      </div>
      )
  }
}

class Child extends React.Component {
  render() {
    return (
      <button onClick={this.props.parentAlert}>
        click me
      </button>
    )
  }
}

let id = document.getElementById('react')
ReactDOM.render(<Parent/>, id)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='react'/>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

假设你有父组件

                       `ContentResolver cr = getApplicationContext().getContentResolver();
                        ContentValues values = new ContentValues();

                        long startMillis = 0;
                        long endMillis = 0;
                        Calendar beginTime = Calendar.getInstance();
                        beginTime.set(EndAn, EndLuna, EndZi, EndOra, 00);
                        startMillis = beginTime.getTimeInMillis();
                        Calendar endTime = Calendar.getInstance();
                        endTime.set(EndAn, EndLuna, EndZi, EndOra, 10);
                        endMillis = endTime.getTimeInMillis();

                        values.put(CalendarContract.Events.DTSTART, startMillis);
                        values.put(CalendarContract.Events.TITLE, headline);
                        values.put(CalendarContract.Events.DESCRIPTION, "Description");

                        TimeZone timeZone = TimeZone.getDefault();
                        values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());

                        values.put(CalendarContract.Events.CALENDAR_ID, 1);

                        values.put(CalendarContract.Events.HAS_ALARM, 1);
                        values.put(CalendarContract.Events.DTEND, endMillis);
                        values.put(CalendarContract.Reminders.MINUTES, 23);
                        values.put(CalendarContract.Reminders.METHOD, 4);
                        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
                                ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(getApplicationContext(), stringPermission , Toast.LENGTH_LONG).show();
                        } else {
                            Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

                            Uri uriContent = CalendarContract.Calendars.CONTENT_URI;
                            String[] projection = new String[]{
                                    CalendarContract.Calendars._ID,
                                    CalendarContract.Calendars.ACCOUNT_NAME,
                                    CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
                                    CalendarContract.Calendars.NAME,
                                    CalendarContract.Calendars.CALENDAR_COLOR,
                                    CalendarContract.Reminders._ID,
                                    CalendarContract.Reminders.MINUTES,
                                    CalendarContract.Reminders.METHOD
                            };

                            Cursor calendarCursor = managedQuery(uriContent, projection, null, null, null);

                        }`

并且你不想像这样从儿童组件中调用切换

import React from 'react';

import Child from './Child';

class CompA extends React.Component {

  toggle = () => {
    alert("Toggle from main class called inside children component");
  }

  render() {
    return (
      <Child toggle={this.toggle} />
    )
  }
}

export default CompA;

然后你只需要传递对你不想从child调用的函数的引用,并在子组件中调用它。您可以随时调用它。我已经把它放在setTimeout中,在3秒后调用它,你可以让你的功能播放,当它结束时再调用它。

答案 2 :(得分:0)

class AAA extend React.Component {
    
    static call_this() {
      return 'Hello World';
    }
    
   // ...
}

class BBB extend React.Component {
    //...
    
   render() {
   
    AAA.call_this(); // return  'Hello World'
   
   }
  
}

但是请记住,您不能在静态方法中访问此关键字。