javascript - React - 如何让这个功能组件改变 div 样式?
问题描述
我有点反应新手所以请对我温柔。我正在尝试构建一个教育应用程序,代码是呈现多项选择答案框:
export default function AnswerBox(props: any) {
return (
<div className="answer-container">
<ul>
{props.answers.map((value: any) => {
return (
<li className="answer-box" key={value.letter} id={value.letter}>
<input className="answer-textbox" type="checkbox" onChange={() => console.log('selected: ', value.letter)}></input>
<span className="answer-letter"><b>{value.letter})</b></span>
{value.answer}
</li>)
})
}
</ul>
</div>
)
}
如您所见,该函数采用数组对象并遍历数组以在无序列表中显示问题字母(例如“A”)和问题答案。
所以这一切都很好,但我希望突出显示列表元素或在实际选择时更改答案框 div。除了将组件更改为有状态组件并使用 state var 来跟踪哪个框被勾选之外,我还没有找到一个好的方法来做到这一点。
但是当我昨晚将它更改为有状态组件时,我真的很难传入要渲染的对象列表。
我怎样才能有一个有状态的类,它也像常规功能组件一样接受道具?
解决方案
首先,您以类似的方式将 props 传递给所有类型的组件,无论它是否有状态。
<Component prop={someValue}/>
唯一的区别是您将如何访问它们。
对于基于类的组件,您可以通过props
class 的属性访问它们this.props
。IE
class Component extends React.Component {
constructor(props) {
// you need to call super(props) otherwise
// this.props will be underfined
super(props);
}
...
someFunction = (...) => {
const value = this.props.prop;
}
}
如果您使用的是 TypeScript,则需要向它描述您的道具的结构和状态,如下所示
interface iComponentProps {
prop: string;
};
interface iComponentState { ... };
export default class Component extends React.Component<iComponentProps, iComponentState> {
...
}
如果您的组件接受道具和/或状态并且您不确定它们的结构,请传递any
您不确定的那个。
另一方面,如果我正确理解了您的问题,您可以执行以下操作:
我还演示了我为解决您的其他问题而制作的简单应用程序。
总之,您可以让您的AnswerBox
组件维护一个与每个选项相关的索引数组,并在每次选择(或单击)选项时通过使用更新它setState
您还可以检查useState
钩子以使您的功能组件有状态。
应用程序.js
import React from "react";
import "./styles.css";
import Question from "./Question";
export default function App() {
const questionData = [
{
question: "Some Question that needs to be answered",
choices: ["Letter A", "Letter B", "Letter C"]
},
{
question: "Another Question that needs to be answered",
choices: ["Letter A", "Letter B", "Letter C"]
}
];
return (
<div className="App">
{questionData.map(question => (
<Question questionText={question.question} choices={question.choices} />
))}
</div>
);
}
问题.js
import React from "react";
import AnswerBox from "./AnswerBox";
const Question = ({ questionText, choices }) => {
return (
<div className={"question-container"}>
<p className={"question-text"}>{questionText}</p>
<AnswerBox choices={choices} />
</div>
);
};
export default Question;
QuestionChoice.js
import React from "react";
import clsx from "clsx";
const QuestionChoice = ({ letter, content, isSelected, handleClick }) => {
return (
<li
className={clsx("question-choice-container", {
"selected-choice": isSelected
})}
>
<input type={"checkbox"} value={content} onClick={handleClick} />
<label for={content} className={"question-choice-label"}>
<strong>{letter.toUpperCase()}. </strong>
<span>{content}</span>
</label>
</li>
);
};
export default QuestionChoice;
答案框.js
import React, { PureComponent } from "react";
import QuestionChoice from "./QuestionChoice";
export default class AnswerBox extends PureComponent {
constructor(props) {
super(props);
this.choiceLetters = Array.from("abcdefghijklmnopqrstuvwxyz");
this.state = { activeChoices: [] };
}
_updateActiveChoices = index => {
let updatedList = [].concat(this.state.activeChoices);
if (this.state.activeChoices.indexOf(index) !== -1) {
updatedList.splice(updatedList.indexOf(index), 1);
} else {
updatedList.push(index);
}
return updatedList;
};
_handleChoiceSelect = choiceIndex => () => {
// an update to your component's state will
// make it re-run its render method
this.setState({ activeChoices: this._updateActiveChoices(choiceIndex) });
};
render() {
return (
<ul class={"answer-box"}>
{this.props.choices.map((choice, index) => (
<QuestionChoice
letter={this.choiceLetters[index]}
content={choice}
isSelected={this.state.activeChoices.indexOf(index) != -1}
handleClick={this._handleChoiceSelect(index)}
/>
))}
</ul>
);
}
}
推荐阅读
- javascript - iDangerous swiper 反向分页
- xamarin - 如何不在 Xamarin.Form Shell Flyout 中显示更多选项卡
- node.js - json2json-transform 中的动态键 - NodeJS
- scala - 在scala中访问外部匹配内部声明的变量
- css - 本地 Jekyll 服务与实际输出不同
- php - Laravel 5.8 表单更新导致空白页面并提交数据显示在地址栏中
- python - numpy 沿着第一个和最后一个出现值出现的轴查找切片
- java - 在 aws 中更改 JSESSIONID 不会让我退出
- javascript - 汉字符号/标点的正则表达式?
- mysql - How to use group concat in a prepared MySQL statement?