#reactjs #react-props
#reactjs #react-props
Вопрос:
Я создаю навигацию в стиле вкладок. И я передал вкладки и их содержимое как дочерние элементы. Как показано ниже
import "./App.css";
import Tabs from "./TranslationPopoverCardComponent/Tabs";
class App extends React.Component {
render() {
return (
<div>
<Tabs>
<span label="Gator">
<button>Butotn here</button>
</span>
<span label="Croc">
After 'while, <em>Crocodile</em>!
</span>
<span label="Sarcosuchus">Nothing to see here,</span>
</Tabs>
</div>
);
}
}
export default App;
Внутри компонента Tabs.
class Tabs extends Component {
constructor(props) {
super(props);
this.state = {
//setting default open tab
activeTab: this.props.children[0],
};
this.changeTab = this.changeTab.bind(this);
}
changeTab(e) {
this.setState({ activeTab: e.target.value });
}
render() {
const tabs = this.props.children.map((child) => {
return (
<span>
<button value={child} onClick={this.changeTab}> // this line here
{child.props.label}
</button>
</span>
);
});
return (
<div>
{tabs}
<br />
{this.state.activeTab}
</div>
);
}
}
export default Tabs;
Вкладка по умолчанию и загружается, как и ожидалось, показывая кнопку. А затем, когда я нажимаю другую вкладку, текст не загружается. Показывает [объект Object] . Могу ли я не передавать props.children в качестве реквизита компонента, а затем устанавливать его как состояние через событие? (что я сделал не так?)
Я пробовал заменить эту строку там child
на with child.props.children
, но тогда компонент button не отображает и не показывает [object Object], а другие работают просто отлично.
Ответ №1:
проблема в том, что inputs/buttons
значение не хранит объект, значение всегда является строкой, поэтому вы видите [object,object]
при нажатии каждой кнопки вкладки (try console.log(typeof e.target.value))
.
кроме того, вам не нужно использовать значение, вместо этого вы можете передать дочерний элемент непосредственно в функцию следующим образом:
<button onClick={() => setActive(child)}>
вот полный код
Ответ №2:
Используйте это в onClick
onClick={() => this.changeTab(child)}
и измените обработчик как
changeTab(e) {
this.setState({ activeTab: e });
}
Ответ №3:
Вы можете просто передать индекс, нажав на вкладку, т.е
const tabs = this.props.children.map((child,i) => {
return (
<span>
<button value={child} onClick={ () => this.changeTab(i)}>
{child.props.label}
</button>
</span>
);
});
и на вкладке изменения сделайте это:
changeTab = (i) => {
this.setState({ activeTab: this.props.children[i] });
}
Вот полный код:
import React from "react";
import "./styles.css";
class Tabs extends React.Component {
constructor(props) {
super(props);
this.state = {
//setting default open tab
activeTab: this.props.children[0]
};
this.changeTab = this.changeTab.bind(this);
}
changeTab = (i) => {
this.setState({ activeTab: this.props.children[i] });
};
render() {
const tabs = this.props.children.map((child, i) => {
return (
<span>
<button value={child} onClick={() => this.changeTab(i)}>
{child.props.label}
</button>
</span>
);
});
return (
<div>
{tabs}
<br />
{this.state.activeTab}
</div>
);
}
}
export default function App() {
return (
<div className="App">
<Tabs>
<span label="Gator">
<button>Button here</button>
</span>
<span label="Croc">
After 'while, <em>Crocodile</em>!
</span>
<span label="Sarcosuchus">Nothing to see here,</span>
</Tabs>
</div>
);
}
Вот демонстрация: https://codesandbox.io/s/cranky-kepler-sr4pz?file=/src/App.js:0-1081