Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 基于公式的动态计算平方英尺_Reactjs_Eval_Formik_Yup - Fatal编程技术网

Reactjs 基于公式的动态计算平方英尺

Reactjs 基于公式的动态计算平方英尺,reactjs,eval,formik,yup,Reactjs,Eval,Formik,Yup,我正在使用React/Formik/Yup和Node/expressapi+Postgres数据库构建一个应用程序。该应用程序的一个功能要求根据包装样式和相关公式计算一个盒子/其他纸板包装的平方英尺。例如,“RSC”样式框的公式为((长*2+宽*2+x1)*(高*2))/144。这两者都作为字符串存储在数据库中的对象中 我当前的解决方案可以运行,但如果用户遗漏了必填字段,应用程序就会崩溃。 我遇到的问题是,不同设计的必填字段会发生变化 import React, { useState, useE

我正在使用React/Formik/Yup和Node/expressapi+Postgres数据库构建一个应用程序。该应用程序的一个功能要求根据包装样式和相关公式计算一个盒子/其他纸板包装的平方英尺。例如,“RSC”样式框的公式为
((长*2+宽*2+x1)*(高*2))/144
。这两者都作为字符串存储在数据库中的对象中

我当前的解决方案可以运行,但如果用户遗漏了必填字段,应用程序就会崩溃。 我遇到的问题是,不同设计的必填字段会发生变化

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

// importing axios for http requests
import axios from 'axios'; 

// Formik/yup (form validation library) import
import { withFormik, Form, Field } from 'formik'
import * as yup from 'yup'; 

// styling imports 
import './BoxCalculator.scss'; 

const BoxCalculator = ({ values,  touched, errors }) => {

    //useState hook to store options we dynamically render in the <select> tag
    const [ boxStyles, setBoxStyles ] = useState(); 

    // pulling the list of possible box formulas from the API on page render, going to save it to an array
    useEffect(() => {
        axios.get('http://localhost:5000/api/box-styles')
        .then(res => {
            setBoxStyles(res.data.data); 
            console.log(boxStyles); 
        })
        .catch(err => {
            console.log(err); 
        }); 
    // this next line eliminates the linter error causes by having an empty dependency array
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    const calculateFootage = () => {
        // selecting the Box Style the user has selected
        const style = document.getElementById('style').value; 

        // filtering the array to find the box_style_formula based on the 
        let styleFormulaArr = boxStyles.filter(box => box.box_style_name === style)
        let formula = styleFormulaArr[0].box_style_formula;

        formula = formula.replace(/length/gi, values.length)
        formula = formula.replace(/width/gi, values.width)
        formula = formula.replace(/height/gi, values.height) 
        formula = formula.replace(/x1/gi, values.x1) 
        formula = formula.replace(/x2/gi, values.x2) 
        formula = formula.replace(/x3/gi, values.x3)   
        formula = formula.replace(/x4/gi, values.x4) 
        formula = formula.replace(/x5/gi, values.x5) 
        formula = formula.replace(/x6/gi, values.x6) 
        formula = formula.replace(/x7/gi, values.x7) 
        formula = formula.replace(/x8/gi, values.x8) 
        formula = formula.replace(/x9/gi, values.x9) 
        formula = formula.replace(/x10/gi, values.x10)

        // disabling the "eval may be harmful" error READ TO UNDERSTAND WHY: https://eslint.org/docs/rules/no-eval
        // eslint-disable-next-line
        const decimal = eval(formula); 


        document.getElementById('sqft').value = `${decimal.toFixed(4)} sq. ft` 
        console.log(document.getElementById('sqft').value)

    }


    if(boxStyles) {
        return ( 
            <>
                <Form className="boxcalc-wrapper">
                    <label>Box Style:<br/>
                        {touched.style && errors.style && <p>{errors.style}</p>}
                        <select type="number"
                        name="style"
                        multiple={false}
                        id="style"
                        className="boxcalc-field"
                        >
                            {boxStyles.map((opt) => {
                                return (<option key={opt.id}>{opt.box_style_name}</option>)
                            })}
                        </select>
                    </label>
                    <label>Length:<br/>
                        {touched.length && errors.length && <p>{errors.length}</p>}
                        <Field type="number"
                        name="length"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>Width:<br/>
                        {touched.width && errors.width && <p>{errors.width}</p>}
                        <Field type="number"
                        name="width"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>Height:<br/>
                        {touched.height && errors.height && <p>{errors.height}</p>}
                        <Field type="number"
                        name="height"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X1:<br/>
                        {touched.x1 && errors.x1 && <p>{errors.x1}</p>}
                        <Field type="number"
                        name="x1"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X2:<br/>
                        {/* {touched.x2 && errors.x2 && <p>{errors.x2}</p>} */}
                        <Field type="number"
                        name="x2"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X3:<br/>
                        <Field type="number"
                        name="x3"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X4:<br/>
                        <Field type="number"
                        name="x4"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X5:<br/>
                        <Field type="number"
                        name="x5"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X6:<br/>
                        <Field type="number"
                        name="x6"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X7:<br/>
                        <Field type="number"
                        name="x7"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X8:<br/>
                        <Field type="number"
                        name="x8"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X9:<br/>
                        <Field type="number"
                        name="x9"
                        className="boxcalc-field"
                        />
                    </label>
                    <label>X10:<br/>
                        <Field type="number"
                        name="x10"
                        className="boxcalc-field"
                        />
                    </label> */}
                    <label>Name Box:<br/>
                        <Field type="number"
                        name="name"
                        className="boxcalc-field"
                        />
                    </label>
                    <button className="calculate-box" onClick={calculateFootage}>Calculate</button>
                    <label>Square Footage:<br/>
                        <Field 
                        type="text"
                        name="footage"
                        className="boxcalc-field"
                        id="sqft"
                        readOnly={true}
                        />
                    </label>
                    <p className="save-question">Need to save this box?</p>
                    <div className="save-btn-wrapper">
                        <p className="no-thanks">No thanks</p>
                        <button className="save-btn">Save</button>
                    </div>
                </Form>
            </>
         );
    } else {
        return <p></p> 
    } 
}

const FormikBoxCalculator = withFormik({
    mapPropsToValues({ style, length, width, height, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, name, sqft, boxStyles }) {
        return {
            style: style || '',
            length: length || '',
            width: width || '',
            height: height || '',
            x1: x1 || '',
            x2: x2 || '', 
            x3: x3 || '', 
            x4: x4 || '', 
            x5: x5 || '', 
            x6: x6 || '', 
            x7: x7 || '', 
            x8: x8 || '', 
            x9: x9 || '', 
            x10: x10 || '',  
            name: name || '',
            sqft: sqft || '',
            boxStyles: boxStyles || ''
        }
    }, 

     ============= YUP VALIDATION SCHEMA ===============
     validationSchema: function createSchema() {
         return yup.object().shape({
             style: yup.string().required("Style is required"),
             length: yup.number().required("Length is required"),
             width: yup.number().required("Width is required"),
             height: yup.number().required("Height is required"),
         })}, 

     ============== END SCHEMA ==============

})(BoxCalculator); 



export default FormikBoxCalculator;
import React,{useState,useffect}来自“React”;
//为http请求导入axios
从“axios”导入axios;
//Formik/yup(表单验证库)导入
从'formik'导入{withFormik,Form,Field}
从“是”以是的形式导入*;
//样式导入
导入“/BoxCalculator.scss”;
const-BoxCalculator=({值,触摸,错误})=>{
//使用state钩子来存储我们在标记中动态呈现的选项
const[boxStyles,setBoxStyles]=useState();
//从页面呈现时的API中提取可能的框公式列表,并将其保存到数组中
useffect(()=>{
axios.get()http://localhost:5000/api/box-样式')
。然后(res=>{
setBoxStyles(res.data.data);
console.log(boxStyles);
})
.catch(错误=>{
控制台日志(err);
}); 
//下一行通过使用空的依赖项数组消除了linter错误导致的错误
//eslint禁用下一行react HOOK/deps
}, [])
常量calculateFootage=()=>{
//选择用户选择的长方体样式
const style=document.getElementById('style').value;
//过滤数组以根据
让styleFormulaArr=boxStyles.filter(box=>box.box\u style\u name===style)
让公式=styleFormulaArr[0]。长方体\u样式\u公式;
公式=公式.replace(/length/gi,values.length)
公式=公式.replace(/width/gi,values.width)
公式=公式.replace(/height/gi,values.height)
公式=公式.replace(/x1/gi,values.x1)
公式=公式.replace(/x2/gi,values.x2)
公式=公式.replace(/x3/gi,values.x3)
公式=公式.replace(/x4/gi,values.x4)
公式=公式.replace(/x5/gi,values.x5)
公式=公式.replace(/x6/gi,values.x6)
公式=公式.replace(/x7/gi,values.x7)
公式=公式.replace(/x8/gi,values.x8)
公式=公式.replace(/x9/gi,values.x9)
公式=公式.replace(/x10/gi,values.x10)
//禁用“eval可能有害”错误读取以了解原因:https://eslint.org/docs/rules/no-eval
//eslint禁用下一行
常量十进制=评估(公式);
document.getElementById('sqft')。value=`${decimal.toFixed(4)}sq.ft`
console.log(document.getElementById('sqft').value)
}
if(boxStyles){
报税表(
方框样式:
{toucted.style&&errors.style&{errors.style}

} {boxStyles.map((opt)=>{ 返回({opt.box\u style\u name}) })} 长度:
{toucted.length&&errors.length&{errors.length}

} 宽度:
{toucted.width&&errors.width&&{errors.width}

} 高度:
{toucted.height&&errors.height&{errors.height}

} X1:
{toucted.x1&&errors.x1&{errors.x1}

} X2:
{/*{toucted.x2&&errors.x2&{errors.x2}

}*/} X3:
X4:
X5:
X6:
X7:
X8:
X9:
X10:
*/} 名称框:
算计 平方英尺:

需要保存此框吗

不用谢

拯救 ); }否则{ 返回

} } 常量FormikBoxCalculator=带formik({ mapPropsToValues({style,length,width,height,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,name,sqft,boxStyles}){ 返回{ 风格:风格| |“, 长度:长度| |“”, 宽度:宽度| |“”, 高度:高度| |“”, x1:x1 | |“”, x2:x2 | |“”, x3:x3 | |“, x4:x4 | |“, x5:x5 | |“, x6:x6 | |“, x7:x7 | |“, x8:x8 | |“, x9:x9 | |“,
const attrs = ['length', 'width', 'height', 'x1', 'x2', 'x3', 'x4', .... etc]
for (i in attrs) {
  const attr = attrs[i];
  if (attr in formula) {
    formula = formula.replace(attr, values[attr])
  }
}