iT邦幫忙

1

[React.js] 如何使用 Hook 將child 的值傳給 parent

目前正在實做https://www.youtube.com/watch?v=9IhsYu4eKJ8
類似這影片的app,
但我的type是select,而不是input,
目前參照 https://codesandbox.io/s/3v2nvvn8yp 程式碼想將child 的select值傳給parent,
但遇到問題,onClick函式已經用來控制select裡面設定的值,
那我該如何再用 onClick 讓 child 去傳送值給parent,

HomeScreen.js[parent]

const SetExamScreen = () => {
const [storeRanges, setStoreRanges] = useState(
    {
        post: {
            ...
        },
        allPost: []
    }
)

const handleChangeValue = e => {
    ...
};

const handleSubmit = e => {
  ...
};

return (
                    <ul>
                        {storeRanges.allPost.map((post, index) => (
                            <li key={index}>
                                <ul className="post-tile">
                                    ...
                                </ul>
                            </li>
                        ))}
                    </ul>
                    <Form>
                        <SetExamForm 
                            handleChangeValue={handleChangeValue}
                            post={storeRanges}
                            handleSubmit={handleSubmit} />
                    </Form>
)
}

child code

const CatagorySelect = ({
      catagorys,catagorySelectedHandler,catagorySelected
  }) => (
  <Form.Control as="select"
      onChange={catagorySelectedHandler}  //onChange already defined
      value={catagorySelected}
      name="catagory"
  >
  ...
);

export default ({ handleChangeValue, handleSubmit, post }) => {
...
  const [catagory, setCatagory] = useState('');

  const catagorySelectedHandler = (e) => {
      setCatagory(e.target.value); //onClick to define this
      setEducation_stage('');
  };

  return (
    <Form>
        <CatagorySelect
            ...
        />
          <Button variant="outline-info" onClick={handleSubmit}>
            add data
          </Button>)}
    </Form>
  )
}

懇請各位大大解答,感謝

1 個回答

1
dragonH
iT邦大師 1 級 ‧ 2020-03-25 10:47:33
最佳解答

如何使用 Hook 將child 的值傳給 parent

codepen

看更多先前的回應...收起先前的回應...
p39212053 iT邦新手 5 級 ‧ 2020-03-25 11:18:22 檢舉

D大,抱歉我想用dictionary的方式儲存,

const Parent = ({ storeRanges }) => {
  return (
    <h1>{ storeRanges.catagory }</h1>
  );
}

const Child = ({ valueHandler }) => {
  return (
    <select className = 'form-control' name="catagory" onChange = { (e) => valueHandler(e.target.value) }>
      {
        Array
          .from({ length: 10 })
          .map((el, index) => (<option value = { index }>{ index }</option>))
      }
    </select>
  );
}

const APP = () => {
  const [storeRanges, setStoreRanges] = React.useState(
        {
            post: {
                catagory: "",
                Education_stage: "",
                grade: "",
                semester: "",
                courseName: "",
                Unit: ""
            },
            allPost: []
        }
    ) 
  const valueHandler = (newValue) => {
    const { name, value } = e.target;

        setStoreRanges(prevState => ({
            post: { ...prevState.post, [name]: value }
        }));
  }
  return (
    <div>
      <Parent value = { storeRanges }/>
      <Child valueHandler = { valueHandler }/>
    </div>
  );
}

ReactDOM.render(
  <APP/>,
  document.querySelector('#app')
);

但是會有無法設定的問題/images/emoticon/emoticon13.gif

dragonH iT邦大師 1 級 ‧ 2020-03-25 11:31:18 檢舉

p39212053

你可能要看一下 console 唷

codepen

有些錯誤

p39212053 iT邦新手 5 級 ‧ 2020-03-25 12:05:56 檢舉

D大,感謝
改成以下就可以run

const Parent = ({ storeRanges }) => {
  console.log("in storeRanges")
  console.log(storeRanges)
  return (
    <h1>{ storeRanges.post.catagory }</h1>
  );
}

const Child = ({ valueHandler }) => {
  return (
    <select className = 'form-control' name="catagory" onChange = { (e) => valueHandler(e) }>
      {
        Array
          .from({ length: 10 })
          .map((el, index) => (<option value = { index }>{ index }</option>))
      }
    </select>
  );
}

const APP = () => {
  const [storeRanges, setStoreRanges] = React.useState(
        {
            post: {
                catagory: "",
                Education_stage: "",
                grade: "",
                semester: "",
                courseName: "",
                Unit: ""
            },
            allPost: []
        }
    ) 
  const valueHandler = (e) => {
    console.log("in valueHandler")
    console.log(e)
    const { name, value } = e.target;

        setStoreRanges(prevState => ({
            post: { ...prevState.post, [name]: value }
        }));
  }
  return (
    <div>
      <Parent storeRanges = { storeRanges }/>
      <Child valueHandler = { valueHandler }/>
    </div>
  );
}

ReactDOM.render(
  <APP/>,
  document.querySelector('#app')
);

但是如果搭配原本https://codepen.io/dragonH/pen/RwPYbgZ?editors=0010
onClick裡已經用來處理控制各select值的狀態,
我有試著在onClick呼叫另外一個函式

Form.Control as="select"
                onChange={(e) => {
                    handleChangeValue(e);
                    catagorySelectedHandler;
                }
                }
                value={catagorySelected}
                name="catagory"
            >

但這樣會有
Expected an assignment or function call and instead saw an expression no-unused-expressions
的問題/images/emoticon/emoticon13.gif

dragonH iT邦大師 1 級 ‧ 2020-03-25 13:12:51 檢舉

p39212053

catagorySelectedHandler 這是啥

function 的話

應該要 catagorySelectedHandler()

p39212053 iT邦新手 5 級 ‧ 2020-03-25 13:50:31 檢舉

D 大非常感謝!!
已解決
/images/emoticon/emoticon32.gif

p39212053 iT邦新手 5 級 ‧ 2020-03-25 16:37:24 檢舉

解決方式是使用
https://codesandbox.io/s/tender-tdd-37stz
的方法,
加上D大的codepen參考
/images/emoticon/emoticon33.gif

dragonH iT邦大師 1 級 ‧ 2020-03-25 21:44:47 檢舉

/images/emoticon/emoticon42.gif

我要發表回答

立即登入回答