React - 触发子组件的getter方法

问题描述 投票:0回答:2

谷歌在这个讨论很多的主题上有很多,但是,我找不到一个明确的解决方案来解决我的问题(可能是常见问题)。

我有一个父组件和一个子组件(见下图),其中子组件生成要存储在某处的值,父组件有一个触发存储操作的按钮:

enter image description here

在这种情况下,父母不希望设置或修改任何子道具或州,而是从中获取一些价值。

对我而言,似乎最好的方法是使用ref并调用子组件方法来获取值;但我正在努力避免使用ref,因为任何反应文档建议。

这是一个用例,我最好使用refs,还是我错过了更好的方法?在这种情况下使用refs有什么缺点?

javascript reactjs
2个回答
1
投票

我个人认为使用refs没有任何问题。它实际上适合您的情况,因为它是按需请求。但是你可以使用文档中描述的Lifting State Up机制。

基本上你会使用回调机制。每次子组件获得输入时,您将调用onChangeInput(input),它是在父组件中实现的。在那里你可以存储它并使用它。


例如,在按钮单击时生成随机数的子组件,以及使用最新项生成的父项从子项生成值:

class Parent extends Component {

    constructor(props) {
        super(props);
        this.childData = null;
    }

    render() {
        return (
            <div>
                <Child onChange={(data) => this.childData = data}/>
                <button onClick={() => console.log("data to be consumed", this.childData)}>Consume Data</button>
            </div>
        )
    }
}

const Child = (props) => (
    <button onClick={() => props.onChange(Math.random())}>Produce Data</button>
);

1
投票
  • 在父级中设置初始状态,以便从子级中获取内容。在这种情况下,temp将存储来自child的数据。
  • 在Parent组件中创建一个getter函数,该函数将获取一个参数。此参数是您尝试传递给父级的数据。
  • 现在你需要一些东西来触发getter函数,所以出于演示目的,我只是添加了一个按钮,当它被单击时,它会将数据从子节点传递给父节点,它将在父节点中呈现。
  • 现在,当单击该按钮时,它将呈现Hello,这是存储在子状态内的内容。 class Parent extends Component { constructor(props) { super(props) this.state = { temp:'', } } getFromChild = (data) => { this.setState({ temp:data }) } render() { return ( <div> <div> THIS IS FROM CHILD: {this.state.temp} </div> <Child getFromChild={this.getFromChild}/> </div> ) } } class Child extends Component { constructor(props) { super(props) this.state = { data:'hello', } } render() { return( <button onClick={() => this.props.getFromChild(this.state.data)}> view data </button> ) } }

第2部分

  • 由于按钮位于父级中,因此我们需要一种方法让孩子知道在单击该按钮时是否传递数据,这就是我们在状态中声明pass的原因。
  • 单击按钮后,pass现在为真。
  • 在子组件内部将调用this.props.getFromChild(this.state.data) class Parent extends Component { constructor(props) { super(props); this.state = { temp: "", pass: false }; } getFromChild = data => { this.setState({ temp: data }); }; passData = () => { this.setState({ pass: true }); }; render() { console.log(this.state.pass); return ( <div> <div> {" "} THIS IS PARENT COMPONENTS STATE:{" "} {!this.state.temp && <div> NOTHING YET </div>} {this.state.temp}{" "} </div> <button onClick={() => this.passData()}> Pass the data </button> <Child temp={this.state.temp} pass={this.state.pass} getFromChild={this.getFromChild} /> </div> ); } } class Child extends Component { constructor(props) { super(props); this.state = { data: "hello" }; } render() { if (this.props.pass & (this.props.temp !== this.state.data)) { this.props.getFromChild(this.state.data); } return ( <div> {" "} This is the child component <br /> state::: data: {this.state.data}{" "} </div> ); } } render(<Parent />, document.getElementById("root")); codesandbox
© www.soinside.com 2019 - 2024. All rights reserved.