programing

외부에서 React 구성 요소 메서드를 호출합니다.

codeshow 2023. 3. 28. 22:22
반응형

외부에서 React 구성 요소 메서드를 호출합니다.

React 요소의 인스턴스에서 React 구성요소에 의해 노출된 메서드를 호출합니다.

예를 들어, 이 jsfiddle에서는요.전화하고 싶다alertMessageHelloElement★★★★★★ 。

추가 래퍼를 작성하지 않고 이 작업을 수행할 수 있는 방법이 있습니까?

편집(JSFiddle에서 복사된 코드)

<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
var onButtonClick = function () {

    //call alertMessage method from the reference of a React Element! Something like HelloElement.alertMessage()
    console.log("clicked!");
}

var Hello = React.createClass({displayName: 'Hello',

    alertMessage: function() {
        alert(this.props.name);                             
    },

    render: function() {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {name: "World"});

React.render(
    HelloElement,
    document.getElementById('container')
);

내부 기능에 액세스하는 방법은 두 가지가 있습니다.하나는 인스턴스 수준이고 다른 하나는 정적 수준입니다.

사례

합니다.React.render아래를 참조해 주세요.

스태틱

리액트 보기JS Statics.단, 스태틱함수는 인스턴스 수준의 데이터에 액세스할 수 없기 때문에thisundefined.

var onButtonClick = function () {
    //call alertMessage method from the reference of a React Element! 
    HelloRendered.alertMessage();
    //call static alertMessage method from the reference of a React Class! 
    Hello.alertMessage();
    console.log("clicked!");
}

var Hello = React.createClass({
    displayName: 'Hello',
    statics: {
        alertMessage: function () {
            alert('static message');
        }
    },
    alertMessage: function () {
        alert(this.props.name);
    },

    render: function () {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {
    name: "World"
});

var HelloRendered = React.render(HelloElement, document.getElementById('container'));

★★★★★★★★★★★★★★★★★★.HelloRendered.alertMessage().

당신은 할 수 있다

import React from 'react';

class Header extends React.Component{

    constructor(){
        super();
        window.helloComponent = this;
    }

    alertMessage(){
       console.log("Called from outside");
    }

    render(){

      return (
      <AppBar style={{background:'#000'}}>
        Hello
      </AppBar>
      )
    }
}

export default Header;

이 컴포넌트 외부에서 다음과 같이 호출할 수 있습니다.

window.helloComponent.alertMessage();

1. 와 함께

const MyComponent = ({myRef}) => {
  const handleClick = () => alert('hello world')
  useImperativeHandle(myRef, () => ({
    handleClick
  }), [/* dependencies (if any) */])
  return (<button onClick={handleClick}>Original Button</button>)
}

MyComponent.defaultProps = {
  myRef: {current: {}}
}

const MyParentComponent = () => {
  const myRef = React.useRef({})
  return (
    <>
      <MyComponent 
        myRef={myRef}
      />
      <button onClick={myRef.current.handleClick}>
        Additional Button
      </button>
    </>
  )
}

2.만

const MyComponent = ({myRef}) => {
  const handleClick = () => alert('hello world')
  myRef.current.handleClick = handleClick
  return (<button onClick={handleClick}>Original Button</button>)
}

MyComponent.defaultProps = {
  myRef: {current: {}}
}

const MyParentComponent = () => {
  const myRef = React.useRef({})
  return (
    <>
      <MyComponent 
        myRef={myRef}
      />
      <button onClick={myRef.current.handleClick}>
        Additional Button
      </button>
    </>
  )
}

행운을 빈다...

나는 다음과 같은 일을 했다.

class Cow extends React.Component {

    constructor (props) {
        super(props);
        this.state = {text: 'hello'};
    }

    componentDidMount () {
        if (this.props.onMounted) {
            this.props.onMounted({
                say: text => this.say(text)
            });
        }
    }

    render () {
        return (
            <pre>
                 ___________________
                < {this.state.text} >
                 -------------------
                        \   ^__^
                         \  (oo)\_______
                            (__)\       )\/\
                                ||----w |
                                ||     ||
            </pre>
        );
    }

    say (text) {
        this.setState({text: text});
    }

}

그리고 또 다른 곳:

class Pasture extends React.Component {

    render () {
        return (
            <div>
                <Cow onMounted={callbacks => this.cowMounted(callbacks)} />
                <button onClick={() => this.changeCow()} />
            </div>
        );
    }

    cowMounted (callbacks) {
        this.cowCallbacks = callbacks;
    }

    changeCow () {
        this.cowCallbacks.say('moo');
    }

}

이 코드를 테스트하지는 않았지만, 이것은 제가 한 프로젝트에서 했던 것과 비슷하며, 잘 작동합니다. :)물론 이것은 좋지 않은 예이므로 소품만 사용해야 합니다만, 제 경우 서브 컴포넌트가 API 호출을 실행했기 때문에 그 컴포넌트 안에 보관하고 싶었습니다.이런 경우에는 이것이 좋은 해결책이다.

render메서드에서는 반환된 값을 사용하지 않을 수 있습니다.이 시점에서 권장되는 접근법은 콜백레퍼런스를 루트 요소에 부가하는 것입니다.다음과 같이 합니다.

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));

창을 통해 접근할 수 있습니다.hello Component 및 그 메서드는 창을 사용하여 액세스할 수 있습니다.hello 컴포넌트방법.

다음은 전체 예입니다.

var onButtonClick = function() {
  window.helloComponent.alertMessage();
}

class Hello extends React.Component {
  alertMessage() {
    alert(this.props.name);
  }

  render() {
    return React.createElement("div", null, "Hello ", this.props.name);
  }
};

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
<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="container"></div>
<button onclick="onButtonClick()">Click me!</button>

추가만 하면 됩니다.onClickdiv)onClick입니다.onClick할 수 .{ }중괄호로 묶으면 경보 메시지가 나타납니다.

컴포넌트 클래스에서 호출할 수 있는 스태틱메서드를 정의하려면 스태틱을 사용해야 합니다.단,

"이 블록 내에서 정의된 메서드는 정적입니다. 즉, 컴포넌트 인스턴스가 생성되기 전에 실행할 수 있으며 메서드는 컴포넌트의 소품이나 상태에 액세스할 수 없습니다.스태틱 방식으로 소품 값을 확인하려면 발신자에게 스태틱 방식으로 소품을 전달하도록 하십시오.(출처)

코드 예시:

    const Hello = React.createClass({

        /*
            The statics object allows you to define static methods that can be called on the component class. For example:
        */
        statics: {
            customMethod: function(foo) {
              return foo === 'bar';
            }
        },


        alertMessage: function() {
            alert(this.props.name);                             
        },

        render: function () {
            return (
                <div onClick={this.alertMessage}>
                Hello {this.props.name}
                </div>
            );
        }
    });

    React.render(<Hello name={'aworld'} />, document.body);

질문을 올바르게 이해했는지 모르기 때문에 조금 도움이 되었으면 합니다.잘못 해석했다면 정정해 주세요.

통계 정보는 권장되지 않습니다.또, 일부 기능을 공개하는 다른 방법들은render난해한 것 같다한편, Stack Overflow가 React의 디버깅에 대해 답변해 준 은 해킹적인 것처럼 보이지만 도움이 되었습니다.

ES6 의 경우는, 다음의 예와 같이, 메서드에 「static」키워드를 사용합니다.static alertMessage: function() { ...
},

Hope는 누구나 도울 수 있습니다.

이 도우미 메서드를 사용하여 구성 요소를 렌더링하고 구성 요소 인스턴스를 반환합니다.그 인스턴스에서 메서드를 호출할 수 있습니다.

static async renderComponentAt(componentClass, props, parentElementId){
         let componentId = props.id;
        if(!componentId){
            throw Error('Component has no id property. Please include id:"...xyz..." to component properties.');
        }

        let parentElement = document.getElementById(parentElementId);

        return await new Promise((resolve, reject) => {
            props.ref = (component)=>{
                resolve(component);
            };
            let element = React.createElement(componentClass, props, null);
            ReactDOM.render(element, parentElement);
        });
    }
class AppProvider extends Component {
  constructor() {
    super();

    window.alertMessage = this.alertMessage.bind(this);
  }

  alertMessage() {
    console.log('Hello World');
 }
}

를 사용하여 창에서 이 메서드를 호출할 수 있습니다.window.alertMessage().

방법 1 using ChildRef:

public childRef: any = React.createRef<Hello>();

public onButtonClick= () => {
    console.log(this.childRef.current); // this will have your child reference
}

<Hello ref = { this.childRef }/>
<button onclick="onButtonClick()">Click me!</button>

방법 2:. using window register

public onButtonClick= () => {
    console.log(window.yourRef); // this will have your child reference
}

<Hello ref = { (ref) => {window.yourRef = ref} }/>`
<button onclick="onButtonClick()">Click me!</button>

React17에서는 Imperative Handle 훅을 사용할 수 있습니다.

useImperativeHandle은 ref를 사용할 때 부모 컴포넌트에 노출되는 인스턴스 값을 사용자 정의합니다.항상 그렇듯이, 대부분의 경우 ref를 사용하는 명령 코드는 피해야 합니다.useImperativeHandle은 forwardRef와 함께 사용해야 합니다.

function FancyInput(props, ref) {
    const inputRef = useRef();
    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current.focus();
        }
    }));

    return <input ref={inputRef} ... />;
}

FancyInput = forwardRef(FancyInput);

이 예에서는 렌더링하는 부모 컴포넌트가 inputRef.current를 호출할 수 있습니다.포커스

이 질문은 끝났지만, 다른 접근방식을 공유하고자 합니다.

다음과 같은 이점이 있습니다.

자 컴포넌트

  1. 자 컴포넌트는 프로포트를 받아들입니다.이것을 onExportedMethods라고 합니다.이 목적은 이 컴포넌트가 소비자에게 제공하는 인스턴스 메서드 세트를 반환하는 것입니다.

  2. 무엇이 노출되어야 하는지에 대한 결정은 건설자 수준에서 이루어집니다.

컨슈머 컴포넌트

  1. prop onExportedMethods & 핸들러 내의 pass 메서드는 Child 컴포넌트가 공개하는 메서드 세트의 복사본을 유지합니다.

  2. 필요할 때마다 부모 컴포넌트가 노출된 메서드를 호출할 수 있습니다.

샘플은 이쪽에서 확인

동적 컴포넌트에는 소품 포함 Get Derived State From Props 메서드를 사용했습니다.

자 컴포넌트의 소품을 갱신하는 기능을 작성할 수 있습니다. 컴포넌트의 get DerivedState FromProps는 소품 갱신을 대신 처리합니다.예를 들어 다음과 같습니다.

class Parent extends React.Component
{
    constructor(props)
    {
        super(props);

        this.state = {  selectMachine: '1' };

        this.setComponent = null;
       
    }

     handleMachineChange = (e) =>{
        this.setState({selectMachine: e.target.value})
    }

}

class Child extends React.Component
{
    state = {
        programForm: {
            machine_id: '1',
           }
    }

    constructor(props)
    {
        super(props);
    }


    static getDerivedStateFromProps(props, state) {
        if(props.selectMachine !== state.programForm.machine_id){
            //Change in props
            return{
                programForm:  { ...state.programForm, machine_id: props.selectMachine }
            };
        }
        return null; // No change to state
    }
}

언급URL : https://stackoverflow.com/questions/31612598/call-a-react-component-method-from-outside

반응형