Я пытаюсь реализовать страницу настроек, где у меня есть общие настройки и какие-то дочерние настройки (в виде слайдера).
Я не могу установить инициал, который передается от родителя.
Я занимаюсь следующими сценариями:
1) Когда все дочерние настройки включены, родительское состояние переключения должно быть включено.
2) Когда какая-либо из дочерних настроек отключена, тогда родители должны переключиться в состояние ожидания
3) Когда все дочерние настройки выключены, родительское состояние должно быть выключено.
4) Также по нажатию кнопки мне нужно получить текущее состояние всех дочерних компонентов.
Если добавить setState внутри componentDidMount внутри parent (может быть, вызов API будет записан внутри него, так что начальные состояния переключателей будут установлены соответствующим образом, а затем будут иметь возможность изменять), дочерние переключатели должны иметь возможность получить значение состояния верно, но здесь этого нет.
И я также вижу, что переключение происходит неправильно. Здесь это происходит, когда вы нажимаете на уже выбранную, что в идеале неправильно
Опробовал следующий подход, но это не похоже на работу. Для этого я использую реагирующее мульти-переключение для этого переключателя.
Может здесь кто-нибудь помочь?
Ссылка песочницы кода: https://codesandbox.io/s/react-multi- тумблер решение - yn3fh
Приложение
import React from "react";
import ReactDOM from "react-dom";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";
import "./styles.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
parentVal: "disabled",
switch1Val: "disabled",
switch2Val: "disabled",
switch3Val: "disabled"
};
}
componentDidMount() {
this.setState({
switch1Val: "enabled",
switch2Val: "disabled",
switch3Val: "enabled"
});
}
onGetChildSwitchValues = () => {
console.log(this.state);
};
setChildSwitchValue = (whichSwitch, value) => {
this.setState(
prevState => Object.assign({}, prevState, { [whichSwitch]: value }),
this.setParentSwitchValue
);
};
setParentSwitchValue = () => {
const { switch1Val, switch2Val, switch3Val } = this.state;
const switchStates = [switch1Val, switch2Val, switch3Val];
const parent = switchStates.every(this.isEnabled)
? "enabled"
: switchStates.every(this.isDisabled)
? "disabled"
: "pending";
this.setState({ parentVal: parent });
};
isEnabled(value) {
return value === "enabled";
}
isDisabled(value) {
return value === "disabled";
}
render() {
const { parentVal, switch1Val, switch2Val, switch3Val } = this.state;
return (
<>
Parent Switch :{" "}
<ParentSwitch
parentSwitch={parentVal}
onSelect={this.setParentSwitchValue}
/>
Child Switches :
<ChildSwitch
childSwitch={switch1Val}
switchName={"switch1Val"}
onSelect={this.setChildSwitchValue}
/>
<ChildSwitch
childSwitch={switch2Val}
switchName={"switch2Val"}
onSelect={this.setChildSwitchValue}
/>
<ChildSwitch
childSwitch={switch3Val}
switchName={"switch3Val"}
onSelect={this.setChildSwitchValue}
/>
<button onClick={this.onGetChildSwitchValues}>Get Child Values</button>
</>
);
}
}
Родитель
import MultiToggle from "react-multi-toggle";
import React from "react";
import "react-multi-toggle/style.css";
class ParentSwitch extends React.Component {
constructor(props) {
super(props);
this.state = {
options: [
{
displayName: "Disabled",
value: "disabled",
optionClass: "red"
},
{
displayName: "Pending",
value: "pending",
optionClass: "grey"
},
{
displayName: "Enabled",
value: "enabled",
optionClass: "green"
}
]
};
}
render() {
const { options } = this.state;
return (
<MultiToggle
options={options}
selectedOption={this.props.parentSwitch}
onSelectOption={() => {}}
/>
);
}
}
export default ParentSwitch;
Ребенок
import MultiToggle from "react-multi-toggle";
import React from "react";
export default class ChildSwitch extends React.Component {
constructor(props) {
super(props);
this.state = {
options: [
{
displayName: "Disabled",
value: "disabled",
optionClass: "red"
},
{
displayName: "Enabled",
value: "enabled",
optionClass: "green"
}
],
selected: ""
};
}
componentDidMount() {
this.setState({ selected: this.props.childSwitch });
}
onSelectOption = selected => {
if (selected === "disabled") {
this.setState({ selected: "enabled" }, () =>
this.props.onSelect(this.props.switchName, "enabled")
);
} else {
this.setState({ selected: "disabled" }, () =>
this.props.onSelect(this.props.switchName, "disabled")
);
}
};
render() {
const { options, selected } = this.state;
return (
<MultiToggle
options={options}
selectedOption={selected}
onSelectOption={this.onSelectOption}
/>
);
}
}
2 ответа
Чтобы решить эту проблему, нужно управлять родительскими и дочерними переключателями из главного компонента. Ознакомьтесь с рабочими раздвоенными кодами и ящиком
< Сильный > APP
import React from "react";
import ReactDOM from "react-dom";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";
import "./styles.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
parentVal: "disabled",
switch1Val: "enabled",
switch2Val: "disabled",
switch3Val: "enabled"
};
}
componentDidMount() {
this.setParentSwitchValue();
}
onGetChildSwitchValues = () => {
console.log(this.state);
};
setChildSwitchValue = (whichSwitch, selected) => {
this.setState(
prevState => ({ ...prevState, [whichSwitch]: selected }),
this.setParentSwitchValue
);
};
setParentSwitchValue = () => {
const { switch1Val, switch2Val, switch3Val } = this.state;
const switchStates = [switch1Val, switch2Val, switch3Val];
let parent = "pending";
if (switchStates.every(val => val === "enabled")) {
parent = "enabled";
}
if (switchStates.every(val => val === "disabled")) {
parent = "disabled";
}
this.setState(prevState => ({ ...prevState, parentVal: parent }));
};
render() {
const { parentVal, switch1Val, switch2Val, switch3Val } = this.state;
return (
<>
Parent Switch :{" "}
<ParentSwitch
parentSwitch={parentVal}
onSelect={this.setParentSwitchValue}
/>
Child Switches :
<ChildSwitch
switchName={"switch1Val"}
selected={switch1Val}
onSelect={this.setChildSwitchValue}
/>
<ChildSwitch
switchName={"switch2Val"}
selected={switch2Val}
onSelect={this.setChildSwitchValue}
/>
<ChildSwitch
switchName={"switch3Val"}
selected={switch3Val}
onSelect={this.setChildSwitchValue}
/>
<button onClick={this.onGetChildSwitchValues}>Get Child Values</button>
</>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Родитель
import MultiToggle from "react-multi-toggle";
import React from "react";
import "react-multi-toggle/style.css";
class ParentSwitch extends React.Component {
constructor(props) {
super(props);
this.state = {
options: [
{
displayName: "Disabled",
value: "disabled",
optionClass: "red"
},
{
displayName: "Pending",
value: "pending",
optionClass: "grey"
},
{
displayName: "Enabled",
value: "enabled",
optionClass: "green"
}
]
};
}
render() {
const { options } = this.state;
return (
<MultiToggle
options={options}
selectedOption={this.props.parentSwitch}
onSelectOption={() => {}}
/>
);
}
}
export default ParentSwitch;
Ребенок
import MultiToggle from "react-multi-toggle";
import React from "react";
import "react-multi-toggle/style.css";
class ParentSwitch extends React.Component {
constructor(props) {
super(props);
this.state = {
options: [
{
displayName: "Disabled",
value: "disabled",
optionClass: "red"
},
{
displayName: "Pending",
value: "pending",
optionClass: "grey"
},
{
displayName: "Enabled",
value: "enabled",
optionClass: "green"
}
]
};
}
render() {
const { options } = this.state;
return (
<MultiToggle
options={options}
selectedOption={this.props.parentSwitch}
onSelectOption={() => {}}
/>
);
}
}
export default ParentSwitch;
Проблема в том, что вы не обновляете локальное состояние при изменении свойства childSwitch
. Так что он останется в отключенном состоянии. Для этого вам нужно добавить метод componentDidUpdate
или просто напрямую использовать свойство без какого-либо локального состояния.
В ChildSwitch
componentDidUpdate(prevProps) {
if(prevProps.childSwitch !== this.props.childSwitch) {
this.setState({ selected: this.props.childSwitch });
}
}
Рабочая вилка: https://codesandbox.io/s/react-multi-toggle -решение - 8xnf3
Похожие вопросы
Связанные вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Обратите внимание, что JavaScript — это НЕ Java. Включите все теги, относящиеся к вашему вопросу: например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [стройный] и т. д.