在 useState 之外调用函数 - React

时间:2021-06-01 18:40:09

标签: reactjs

我正在创建我的第一个 React 项目,我想调用我创建的 Canvas 元素中的“Text”函数,但我不知道该怎么做。

我想在用户点击“计算”按钮时调用该函数。

这是我做的:`

import React, { useState, useRef, useEffect } from "react";
import "./styles.css";




function GetSideValues() {
  const [values, setValues] = useState({
    AB: "",
    BC: "",
    AC: ""
  });



  function IfFilledCorrectly() {
    if (!values.AB || !values.BC || !values.AC) {
      alert("Please, enter all values");
    } else if (
      parseInt(values.AB, 10) <= 0 ||
      parseInt(values.BC, 10) <= 0 ||
      parseInt(values.AC, 10) <= 0
    ) {
      alert("Side length cannot be 0 or less");
    }
  }

  const set = (side_len) => {
    return ({ target: { value } }) => {
      setValues((oldValues) => ({ ...oldValues, [side_len]: value }));
    };
  };
 
  const Canvas = props => {
    
    const canvasRef = useRef(null)
    if(values.AB && values.BC && values.AC){
    values.AB = parseInt(values.AB,10) 
    values.BC = parseInt(values.BC,10) 
    values.AC = parseInt(values.AC,10) 
    }

    let AB =  values.AB * 10
    let BC = values.BC * 10
    let AC = values.AC * 10


    let Cx = (AC*AC - BC*BC + AB*AB) / (2*AB)
  
   
    const draw = ctx => {

      let path=new Path2D();
      ctx.strokeStyle = "black";
      path.moveTo(120,20);
      path.lineTo(AB + 120,20);
      path.lineTo(Cx  + 120 ,Math.sqrt(AC*AC - Cx*Cx) + 20 );
      path.lineTo(120, 20);
      
      ctx.fillStyle = "white";
      ctx.fill(path);
      ctx.stroke(path)

      const triangleType = (side1,side2,side3) => {

        //check, if exists
        if (side1 + side2 <= side3 || side1 + side3 <= side2 || side2 + side3 <= side1){
            return "Non existing"
        }
    
        if(side1 === side2 && side2 === side3 ){
         
            return "Equilateral"
        }
    
        if(side1 === side2 || side1 === side3 || side2 === side3){
            return "Isosceles"
        }
    
        return "Scalene"
    
    }
    

    function Text(){
      if(values.AB && values.BC && values.AC){
      ctx.font = "900 20px Verdana";
      ctx.fillStyle = "black";
      ctx.fillText(triangleType(AB,BC,AC), 90 , 130);
      }
    }

 
    

    
  }
  
    
    useEffect(() => {
      
      const canvas = canvasRef.current
      const context = canvas.getContext('2d')
      
      //Our draw come here
      
      draw(context)
    }, [draw])
    
    return <canvas ref={canvasRef} {...props}/>
  }



  return (
    <div className="container-fluid">
      <div className="row justify-content-center">
        <div id="container" className="col-lg-4 col-md-6 col-sm-9 col-11">
          
           <Canvas />
          

          <fieldset>
            <legend>A side</legend>
            <input
              type="number"
              required
              min="1"
              value={values.AB}
              onChange={set("AB")}
            />
          </fieldset>

          <fieldset>
            <legend>B side</legend>
            <input
              type="number"
              required
              min="1"
              value={values.BC}
              onChange={set("BC")}
            />
          </fieldset>

          <fieldset>
            <legend>C side</legend>
            <input
              type="number"
              required
              min="1"
              value={values.AC}
              onChange={set("AC")}
            />
          </fieldset>

          <button
            id="calculate-btn"
            className="btn btn-sm btn-dark calculate-btn"
            onClick={IfFilledCorrectly} onClick={values.Text()}
          >
            Calculate
          </button>
        </div>
      </div>
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <GetSideValues />
      
    </div>
  );
}

我尝试了不同的方法 - 我将 Text 函数放在外面并像这样写“onClick={values.Text}”,但它也没有奏效。

`

1 个答案:

答案 0 :(得分:0)

您需要在考虑状态时考虑这个问题。例如,如果您单击按钮,则同一组件下的文本会发生变化。

  const Component = () => {
   const [text, setText] = useText('')
   const onClick = () => { setText('Hello') }
   return <button onClick={onClick} />
  }

请记住,有一个 setText,即使您抓住了一个 ref,如果它不是状态,您也不会看到变化。

此外,您的代码充满了大写和小写字母,例如。 canvasCanvas。确保它是一个组件,不要使用小写字母。