简体   繁体   English

有条件地更新父类传递的事件处理程序中子组件的 state

[英]Conditionally updating child component's state in event-handler passed by Parent-class

const Child = (props) => {
  const [val, setVal] = useState(props.val);

  const handleCreate = (newData) => new Promise((resolve, reject) => {
        setTimeout(() => {
            {
                const transactions = JSON.parse(JSON.stringify(tableData));
                const clean_transaction = getCleanTransaction(newData);
                const db_transaction = convertToDbInterface(clean_transaction);
                transactions.push(clean_transaction);
// The below code makes post-request to 2 APIs synchronously and conditionally updates the child-state if calls are successful.
                **categoryPostRequest(clean_transaction)
                    .then(category_res => {
                        console.log('cat-add-res:', category_res);
                        transactionPostRequest(clean_transaction)
                            .then(transaction_res => {
                                addToast('Added successfully', { appearance: 'success'});
                                **setVal(transactions)**
                            }).catch(tr_err => {
                            addToast(tr_err.message, {appearance: 'error'});
                        })
                    }).catch(category_err => {
                    console.log(category_err);
                    addToast(category_err.message, {appearance: 'error'})
                });**
            }
            resolve()
        }, 1000)
    });

  return (
    <MaterialTable
            title={props.title}
            data={val}
            editable={{
                onRowAdd: handleCreate
            }}
        />
  );
}

const Parent = (props) => {
  // some other stuff to generate val
  return (
    <Child val={val}/>
  );
}

I am struggling to achieve this: I'd like to move the post-request part of the function in handleCreate (bold-section), over to the Parent-component that can be called by the Child-class.我正在努力实现这一点:我想将句柄创建(粗体部分)中 function 的请求后部分移到可由子类调用的父组件。 The idea is to make the Component abstract and re-usable by other similar Parent-classes.这个想法是使组件抽象并可由其他类似的父类重用。

Create the function in the parent, and pass it to the child in the props:在parent中创建function,并在props中传给child:

const Parent = (props) => {
  // The handler
  const onCreate = /*...*/;

  // some other stuff
  return (
    <Child ...props onCreate={onCreate}/>
  );
}

Then have the child call the function with any parameters it needs (there don't seem to be any in your example, you're not using val in it for instance):然后让孩子使用它需要的任何参数调用 function (您的示例中似乎没有任何参数,例如,您没有在其中使用val ):

return (
  <MaterialTable
          title={props.title}
          data={val}
          editable={{
              onRowAdd: props.onCreate // Or `onRowAdd: () => props.onCreate(parameters, go, here)`
          }}
      />
);

Side note: There's no reason to copy props.val to val state member within the child component, just use props.val .旁注:没有理由将props.val复制到子组件中的val state 成员,只需使用props.val

Side note 2: Destructuring is often handy with props:旁注 2:解构通常对 props 很方便:

const Child = ({val, onCreate}) => {
  // ...
};

Side note 3: You have your Parent component calling Child with all of its props, via ...props :旁注 3:您的Parent组件通过...props调用Child及其所有道具:

return (
  <Child ...props onCreate={onCreate}/>
);

That's generally not best.这通常不是最好的。 Only pass Child what it actually needs, in this case, val and onCreate :只传递Child它实际需要的东西,在这种情况下, valonCreate

return (
  <Child val={props.val} onCreate={onCreate}/>
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM