首页 > 解决方案 > React Checkbox 触发正则表达式

问题描述

附加我的代码 - 使用 create-react-app 构建。研究用于搜索输入的小组件。如果匹配则突出显示单词,如果不匹配则继续显示其他文本。

当前解决方案在调用后会在所有文本上显示标记。

import React, { useState } from "react";

const app = (props) => {
  const [value, setValue] = useState("");
  const [searchValue, setSearchValue] = useState("");
  const [checked, setChecked] = useState(false);
  const [sensitive, setSensitive] = useState("i");
  let highlight = null;

  const handleChange = (event) => {
    setValue(event.target.value);
  };
  console.log(value);

  const handleSearchChange = (event) => {
    setSearchValue(event.target.value);
  };
  console.log(searchValue); 

  const getHighlightedText = (value, searchValue) => {
    let regex = new RegExp(`(${searchValue})`, `g${sensitive}`);
    console.log(regex);
    const parts = value.split(regex);
    //console.log(parts);
    highlight = <span> { parts.map((part, i) => 
        <span key={i} style={part === searchValue ? { backgroundColor: 'Yellow' } : {} }>
            { part }
        </span>)
    } </span>;
  }

  const checkedTest = () => {
    if(checked === true) {
      setSensitive(" ") // makes it case sensitive
      console.log(sensitive);
      setChecked(true);
    } else {
      setSensitive("i")
      console.log(sensitive);
      setChecked(false);
    }
  }

  return (
    <>
      <form className="text-search-form">
        <textarea className="source-text" value={value} onChange={handleChange}/>
        <input className="search-term" value={searchValue} onChange={handleSearchChange} onKeyPress={getHighlightedText(value, searchValue)} />
        <label htmlFor="caseSensitive">case sensitive?
          <input 
            type="checkbox" 
            className="case-sensitive" 
            name="caseSensitive" 
            defaultChecked={checked} 
            onClick={getHighlightedText(value, searchValue)}
            onChange={checkedTest} 
             />
        </label>
      </form>
      <div className="result">{highlight}</div>
    </>
  );
};

export default Highlighter;

调整代码以显示我正确的组件名称。

标签: javascriptregex

解决方案


这应该按预期工作

删除了所有手动调用,getHighlightedText而是将其移至 JSX 并删除了其参数(可能不是一个好主意)。原因是所 getHighlightedText依赖的值都处于函数状态,并且任何更改都会触发重新渲染,该重新渲染会自动调用该函数。

其次,固定你的checkedTest,这更干净。

第三,您在部件迭代中进行的比较不是不区分大小写的,因此即使您的正则表达式不区分大小写,===字符串也不是这样,将其移至单独的函数并处理这两种情况。通过将 part 和 searchvalue 都转换为普通大小写来处理不敏感的大小写,在本例中为小写。

与往常一样,这可以得到更多改进,但我认为它可以解决您的问题。

演示: codesandbox

import React, { useState } from "react";

const App = props => {
  const [value, setValue] = useState("");
  const [searchValue, setSearchValue] = useState("");
  const [checked, setChecked] = useState(false);
  const [sensitive, setSensitive] = useState("i");

  const handleChange = event => {
    setValue(event.target.value);
  };

  const handleSearchChange = event => {
    setSearchValue(event.target.value);
  };

  const getHighlightColor = part => {
    let isEqual = false;
    if (checked) {
      isEqual = part === searchValue;
    } else {
      isEqual = part.toLowerCase() === searchValue.toLowerCase();
    }
    return isEqual ? "Yellow" : "transperant";
  };

  const getHighlightedText = () => {
    let regex = new RegExp(`(${searchValue})`, `g${sensitive}`);
    const parts = value.split(regex);
    if (searchValue)
      return (
        <span>
          {parts.map((part, i) => (
            <span key={i} style={{ backgroundColor: getHighlightColor(part) }}>
              {part}
            </span>
          ))}
        </span>
      );
  };

  const checkedTest = event => {
    setChecked(event.target.checked);
    setSensitive(event.target.checked ? "" : "i");
  };
  return (
    <>
      <form className="text-search-form">
        <textarea
          className="source-text"
          value={value}
          onChange={handleChange}
        />
        <input
          className="search-term"
          value={searchValue}
          onChange={handleSearchChange}
        />
        <label htmlFor="caseSensitive">
          case sensitive?
          <input
            type="checkbox"
            className="case-sensitive"
            name="caseSensitive"
            defaultChecked={checked}
            onChange={checkedTest}
          />
        </label>
      </form>
      <div className="result">{getHighlightedText()}</div>
    </>
  );
};
export default App;


推荐阅读