简体   繁体   中英

Pulling a setState from child component and then using it as a value in parent component

I created a stopwatch and I am attempting to take the value of the stopwatch and pass it through a form component. Currently, when trying to push it through using 'props', it isn't connecting to the specific 'setTime' const determined in the StopWatch component.

I am using react-hook-form, and Styled Components throughout the project. And currently I don't have anything passed through my "value" in my controller because everything I'm trying to do just isn't working.

Here is the stop watch component:

import React, { useEffect, useState } from "react";

const StopWatch = (props) => {
  const [time, setTime] = useState(0);
  const [timerOn, setTimeOn] = useState(false);

  useEffect(() => {
    let interval = null;

    if (timerOn) {
      interval = setInterval(() => {
        setTime((prevTime) => prevTime + 10);
      }, 10);
    } else {
      clearInterval(interval);
    }

    return () => clearInterval(interval);
  }, [timerOn]);

  //   const updateTimeLogged = (e) => {
  //     props.setTimeOn(e.target.value);
  //   };

  return (
    <div>
      <div>
        <span>{("0" + Math.floor((time / 60000) % 60)).slice(-2)}:</span>
        <span>{("0" + Math.floor((time / 1000) % 60)).slice(-2)}:</span>
        <span>{("0" + ((time / 10) % 100)).slice(-2)}</span>
      </div>
      <div>
        {!timerOn && time === 0 && (
          <button onClick={() => setTimeOn(true)}>Start</button>
        )}
        {timerOn && <button onClick={() => setTimeOn(false)}>Stop</button>}
        {!timerOn && time !== 0 && (
          <button onClick={() => setTimeOn(true)}>Resume</button>
        )}
        {!timerOn && time > 0 && (
          <button onClick={() => setTime(0)}>Reset</button>
        )}
      </div>
    </div>
  );
};

export default StopWatch;

And here is my form component:

import {
  Button,
  Form,
  Input,
  GridContainer,
  Label,
  InputWrapper,
  DateWrapper,
  NotesWrapper,
  StopWatchWrapper,
} from "./PracticeLog.styled";
import { useForm, Controller } from "react-hook-form";
import { useState } from "react";
import StopWatch from "./StopWatch";



const PracticeLogInput = (props) => {
  const { register, handleSubmit, control } = useForm();
  const [result, setResult] = useState("");

  const onSubmit = (data) => console.log(data);

 

  return (
    <GridContainer>
      <Form onSubmit={handleSubmit(onSubmit)}>
        <DateWrapper>
          <Label>Date</Label>
          <Input type="date" {...register("Date")} placeholder="Date"></Input>
        </DateWrapper>
        <NotesWrapper>
          <Label>Notes</Label>
          <Input type="text" {...register("Notes")} placeholder="Notes"></Input>
        </NotesWrapper>
        <StopWatchWrapper>
          <Controller
            name="time"
            control={control}
            onChange={(e) => setInterval(e.target.value)}
            value={}  //<-- this is where I need to put the value I get from 'setTime' in '/.StopWatch'.
            render={StopWatch}
          />
        </StopWatchWrapper>
        <Button type="Submit">Submit</Button>
      </Form>
    </GridContainer>
  );
};

export default PracticeLogInput;

If you see anything I can improve on, please let me know.

Try using this code but your code is little bit complex try making it simpler bro

    import {
  Button,
  Form,
  Input,
  GridContainer,
  Label,
  InputWrapper,
  DateWrapper,
  NotesWrapper,
  StopWatchWrapper,
} from "./PracticeLog.styled";
import { useForm, Controller } from "react-hook-form";
import { useState } from "react";
import StopWatch from "./StopWatch";



const PracticeLogInput = (props) => {
  const { register, handleSubmit, control } = useForm();
  const [time, setTime] = useState(0)
  const [result, setResult] = useState("");

  const onSubmit = (data) => console.log(data);

 

  return (
    <GridContainer>
      <Form onSubmit={handleSubmit(onSubmit)}>
        <DateWrapper>
          <Label>Date</Label>
          <Input type="date" {...register("Date")} placeholder="Date"></Input>
        </DateWrapper>
        <NotesWrapper>
          <Label>Notes</Label>
          <Input type="text" {...register("Notes")} placeholder="Notes"></Input>
        </NotesWrapper>
        <StopWatchWrapper>
          <Controller
            name="time"
            control={control}
            onChange={(e) => setInterval(e.target.value)}
            value={time}  //<-- this is where I need to put the value I get from 'setTime' in '/.StopWatch'.
            render={<StopWatch
time={time}
setTime={setTime}
/>}
          />
        </StopWatchWrapper>
        <Button type="Submit">Submit</Button>
      </Form>
    </GridContainer>
  );
};

export default PracticeLogInput;

And in StopWatch component change the code like this

    const StopWatch = (props) => {
      const {time,setTime}=props
      const [timerOn, setTimeOn] = useState(false

);
//rest

Note: The flow is like parent to child you can't pull a state from child to parent directly instead define the state in parent and pass it as props to child. And change the state from child using the props itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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