У меня есть такие компоненты:
class DashTopNav extends React.Component {
constructor(props) {
super(props);
}
render(){
return(<button></button>);
}
}
class FltBox extends React.Component {
constructor(props) {
super(props);
}
methodToFired(){
}
}
class XDashBoard extends React.Component {
constructor(props) {
super(props);
}
render(){
return(<div className = "XDashBoard">
<DashTopNav onClick = {call methodToFired on FltBox} />
<FltBox />
</div>);
}
}
Я хочу вызвать метод на FltBox (methodToFired) с помощью кнопки на DashTopNav, но я не могу найти способ вызвать функцию дочернего компонента из другого дочернего компонента.
Нет, потому что мне нужно что-то извлечь во FltBox при нажатии кнопки на DashTopNav: /
Скорее всего, это нет, что вы хотите делать.
Мне кажется, что вы хотите извлечь methodToFired
из компонента FltBox
в свой компонент XDashBoard
, поскольку он кажется универсальным типом метода и передать его в качестве опоры вашему компоненту DashTopNav
или использовать шаблон Flux для запуска действия из ваш DashTopNav
, на который затем отвечает ваш FltBox
.
Ваш примерный код слишком скудный, чтобы сделать правильное предположение, но ниже приведен рабочий рефакторинг, который, скорее всего, вам больше подойдет.
class DashTopNav extends React.Component {
constructor(props) {
super(props);
}
render() {
return(<button {...this.props}>Button</button>);
}
}
class XDashBoard extends React.Component {
constructor(props) {
super(props);
}
methodToFired (e) {
console.info('fired');
}
render() {
return(
<div className = "XDashBoard">
<DashTopNav onClick = {this.methodToFired} />
</div>
);
}
}
С React вы не должны пытаться получить доступ к другому компонентному методу произвольно. По сути, React так не спроектирован. Компоненты React реагируют на изменения в своих свойствах и состояниях, поэтому вы можете управлять ими, изменяя их свойства и состояния.
В вашем примере вы можете передать метод класса из родительского компонента в DashTopNav.onClick
и изменить реквизиты FltBox
внутри этой функции, заставив FltBox
повторно отрисовывать и обновлять, когда пользователь щелкает DashTopNav
.
Если конечный результат FltBox
может быть получен непосредственно из этого изменения реквизита, тогда функции render
достаточно, если вам нужно выполнить побочный эффект в качестве реакции на изменение реквизита, тогда вы можете использовать методы жизненного цикла React, такие как didComponentUpdate
.
Например:
class DashTopNav extends React.Component {
constructor(props) {
super(props);
}
render(){
return(<button></button>);
}
}
class FltBox extends React.Component {
constructor(props) {
super(props);
}
didComponentUpdate() {
// Handle navButtonClick update
}
}
class XDashBoard extends React.Component {
constructor(props) {
super(props);
this.state = {
navButtonClick: false
};
}
handleNavClick = () => {
this.setState({navButtonClick: true});
}
render(){
const {navButtonClick} = this.state;
return(
<div className = "XDashBoard">
<DashTopNav onClick = {this.handleNavClick} />
<FltBox navButtonClick />
</div>
);
}
}
Вы можете использовать реф.
Используя ссылки, мы можем получить доступ к узлам DOM или элементам React, созданным в методе рендеринга, в этом примере мы будем использовать ссылки для доступа к элементу, который содержит methodToFired
в компоненте FltBox
, мы будем использовать элемент div
, таким образом, мы можем получить доступ к methodToFired
.
затем мы будем использовать эту ссылку для элемента div и передать ее любому компоненту, который мы хотим, в нашем случае DashTopNav
в качестве опоры, которая является onClick = {this.parentClickHandler}
class FltBox extends React.Component {
constructor(props) {
super(props);
}
methodToFired(){
alert('Fired from FltBox')
}
// here we use ref to access to the div element
render() {
return (<div ref = {div => this.div = div}></div>);
}
}
class DashTopNav extends React.Component {
constructor(props) {
super(props);
}
render(){
return (
<button onClick = {this.props.onClick}>Submit</button>
);
}
}
class XDashBoard extends React.Component {
constructor(props) {
super(props);
this.parentClickHandler = this.parentClickHandler.bind(this)
}
parentClickHandler() {
this.mydiv.methodToFired();
}
render(){
return(<div className = "XDashBoard">
<DashTopNav onClick = {this.parentClickHandler} />
<FltBox ref = {div => this.mydiv = div}/>
</div>);
}
}
ReactDOM.render(<XDashBoard />, document.querySelector("#app"))
<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 = "app"></div>
было бы лучше поместить
methodToFired
вDashTopNav
, так как вы не используете его вFltBox
, верно?