如何在 React js 中单击时更改 div 背景?
Posted
技术标签:
【中文标题】如何在 React js 中单击时更改 div 背景?【英文标题】:How to change div background on click in React js? 【发布时间】:2022-01-05 11:39:23 【问题描述】:我正在将 Question.js 文件中的问题列表提取到 Home.js
当用户点击答案时,如何更改答案边框颜色。 如果用户点击正确的答案,我想变成绿色,如果用户点击错误的答案,我想变成红色。
如果用户点击了错误的答案,那么它应该通过使背景变为绿色来显示正确的答案,其余的都应该变成红色边框。
查看输出:
Home.js 文件:
import React from 'react'
import Questions from './Questions'
const Home = () =>
function action()
return (
<>
<div className="main">
Questions.map((item)=>(
<div className="box">
<div className="title">
<h2 className="qno">item.numb</h2>
<h2> item.question</h2>
</div>
<div className="options">
<span onClick=()=>action() >item.options.q1</span>
<span>item.options.q2</span>
<span>item.options.q3</span>
<span>item.options.q4</span>
</div>
</div>
))
</div>
</>
)
export default Home;
Questions.js 文件:
let Questions = [
numb: 1,
question: "What does html stand for?",
answer: "Hyper Text Markup Language",
options:
q1: "Hyper Text Preprocessor",
q2: "Hyper Text Markup Language",
q3: "Hyper Text Multiple Language",
q4: "Hyper Tool Multi Language",
,
,
numb: 2,
question: "Who is Ankit Yadav?",
answer: "Engineer",
options:
q1: "Engineer",
q2: "Doctor",
q3: "CEO",
q4: "Scientist",
,
,
];
export default Questions;
style.css 文件:
/* styling */
.main
width: 70vw;
height: 100%;
box-shadow: 0 0 14px 0;
margin: 30px auto;
border-radius: 5px;
.box
padding: 10px;
border-bottom: 2px solid #4c4c4c;
.title .qno
font-size: 1.7rem;
font-weight: 800;
font-family: 'Courier New', Courier, monospace;
background-color: #4c4c4c;
padding: 5px;
border-radius: 70px;
color: #fff;
.title h2
font-size: 1.7rem;
font-weight: 500;
margin-left: 10px;
.box .title
display: flex;
.options
display: flex;
flex-direction: column;
justify-content: space-between;
margin: 20px 25px;
【问题讨论】:
创建一个ref
并使用引用el.style.border = "2px solid green";
或类似的东西。
【参考方案1】:
我建议创建名为Question
的单独组件,以避免使用数据数组并将状态登录放入其中。但如果这不可能,我会这样做:
Home.js
import React from 'react'
import Questions from './Questions'
const Home = () =>
// Add this two state values
const highlightedRightIds, setHighlightedRightIds = useState([]);
const highlightedWrongIds, setHighlightedWrongIds = useState([]);
// Handle click here
const handleClick = (questionId, isRight) =>
setHighlightedWrongIds([...highlightedWrongIds, questionId]);
if (isRight)
setHighlightedRightIds([...highlightedRightIds, questionId]);
return (
<>
<div className="main">
Questions.map((item)=>(
<div className="box">
<div className="title">
<h2 className="qno">item.numb</h2>
<h2> item.question</h2>
</div>
<div className="options">
// use map to render a list of options
item.options.map(option =>
const isRight = option === item.answer;
const highlight = isRight
? highlightedRightIds.includes(item.numb)
: highlightedWrongIds.includes(item.numb);
const highlightClass = isRight
? "rightAnswer"
: "wrongAnswer";
return <span
onClick=() => handleClick(item.numb, isRight)
className=highlight ? highlightClass : ""
>
option
</span>;
)
</div>
</div>
))
</div>
</>
)
export default Home;
style.css(添加新类)
// ... other styles
.rightAnswer
background-color: green;
.wrongAnswer
border-color: red;
【讨论】:
【参考方案2】:您可以使用inline styles
和一些实用函数来实现它
const Home = () =>
const [answerStatus, setAnswerStatus] = useState(() =>
return Questions.map((item) =>
return
numb: item.numb,
answered: false,
givenAnswer: ""
;
);
);
const action = (questionNumber, answer) =>
setAnswerStatus((prevState) =>
return prevState.map((item) =>
item.numb === questionNumber
? ...item, answered: true, givenAnswer: answer
: item
);
);
;
const isAnswerCorrect = (questionNumber) =>
const status = answerStatus.find((item) => item.numb === questionNumber);
const question = Questions.find((item) => item.numb === questionNumber);
return status.answered && question.answer === status.givenAnswer;
;
const questionAnswered = (questionNumber) =>
const status = answerStatus.find((item) => item.numb === questionNumber);
return status.answered;
;
const getGivenAnswer = (questionNumber) =>
return answerStatus.find((item) => item.numb === questionNumber)
?.givenAnswer;
;
return (
<>
<div className="main">
Questions.map((item) => (
<div className="box">
<div className="title">
<h2 className="qno">item.numb</h2>
<h2> item.question</h2>
</div>
<div className="options">
Object.entries(item.options).map(([optionId, optionDesc]) =>
return (
<span
onClick=() => action(item.numb, optionDesc)
style=
backgroundColor: questionAnswered(item.numb)
? isAnswerCorrect(item.numb) &&
getGivenAnswer(item.numb) === optionDesc
? "lightgreen"
: isAnswerCorrect(item.numb)
? "lightblue"
: item.answer !== optionDesc
? "tomato"
: "lightgreen"
: "lightblue",
padding: "5px",
borderRadius: "3px",
margin: "3px",
cursor: "pointer"
>
optionDesc
questionAnswered(item.numb) &&
getGivenAnswer(item.numb) === optionDesc &&
" (given answer)"
</span>
);
)
</div>
</div>
))
</div>
</>
);
;
export default Home;
代码沙箱 => https://codesandbox.io/s/quirky-hill-cwoc5?file=/src/App.js
【讨论】:
@Ankit Kumar,看看这个!! 如何添加功能初始化,就像用户选择一个选项后,他应该无法再次单击该问题中的其他选项? 像这样更改onClick
ahndler => onClick=() => !questionAnswered(item.numb) && action(item.numb, optionDesc)
并将光标的跨度样式更改为cursor: !questionAnswered(item.numb) ? "pointer" : "not-allowed"
我只想将用户点击的错误选项设为红色,而不是所有错误的选项都应为红色。如何做到这一点。
@AnkitKumar,更新了代码沙箱以上是关于如何在 React js 中单击时更改 div 背景?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 中应用 classNames 以更改 React 中子 div 之一的背景颜色
如何更改 html 或 javascript 代码,所以当我单击 div 时,即使它不起作用。我该如何解决?
React.js - 如何使用 axios POST 方法将数据从 div 传递到函数?