I've seen this question asked before but have not seen an answer. I have two tabs for now but neither tab shows any content. I've pared it all back to its most basic functioning. I'm not trying to display a component in the tab; just an h1 for now. Based on a comment from here I added a link to the header of my index.html and it is still a stubborn no-show. Here's what I'm working with:
import React, { Component, useState } from 'react';
import Tabs from 'react-bootstrap/Tabs';
import Tab from 'react-bootstrap/Tab';
export class GameHome extends Component {
static displayName = GameHome.name;
constructor(props) {
super(props);
this.state = {
};
this.componentDidMount = this.componentDidMount.bind(this);
}
componentDidMount() {
}
render = () => {
return (
<Tabs defaultActiveKey="tab1" id="uncontrolledTabs">
<Tab eventKey="tab1" title="Tab 1">
<h1>Tab 1</h1>
</Tab>
<Tab eventKey="tab2" title="Tab 2">
<h1>Tab 2</h1>
</Tab>
</Tabs>
);
}
}
Related
Quite new at this and have a question with something that I feel like should be an easy answer.
I essentially have a page that has 5 titles. When I click on a title, it will render that component. I have that, but I don't know how to then make the 5 titles go away? The component that is rendered just shows up below the titles and I want them to switch entirely. Have done a lot of googling and can't seem to get it right.
XYZ.js
import '../App.css';
import Button from 'react-bootstrap/Button'
import { BrowserRouter, Route, Router, Link } from "react-router-dom";
import Chat from './chat.js';
export class XYZ extends React.Component {
constructor(props) {
super(props);
this.state = {
showChat: false,
};
this._onChatClick = this._onChatClick.bind(this);
}
_onChatClick() {
this.setState({
showChat: !this.state.showChat,
});
}
render() {
return (
<div className="yyy">
<div className="xxx">
<div className="chatBody">
<Button className="chatTitle" onClick={this._onChatClick}>
Chat xxz
</Button>
{this.state.showChat ?
<Chat /> : null
}
</div>
<div>
....brevity
</div>
</div>
</div>
);
}
}
export default XYZ;
Thank you for any help!! Can supply additional files if necessary
Can' comment but I guess that you want <Button className="chatTitle"> to disappear when you click on it.
You need to either put it in the place of the null in your ternary operator or put another conditional rendering on top of the existing one, like:
{!this.state.showChat && <Button className="chatTitle">Chat xxz</Button>}
I have troubles with scrolling down my component. I want scroll bar thumb to be at the very end of chat div from the start. I am not sure what the probleme is here. MessageTo and MessageFrom are components that represent paragraphs with text and display author's name. ChatInput is textarea with send button.
import React from 'react';
import './index.css';
import MessageFrom from './message-from';
import MessageTo from './message-to';
import ChatInput from './chat-input';
import SimpleBarReact from 'simplebar-react';
import 'simplebar/src/simplebar.css';
class Chat extends React.Component {
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate(){
this.scrollToBottom()
}
scrollToBottom = () => {
this.el.scrollIntoView({behavior:"smooth"});
}
render(){
return(
<div className="chat" id="slider-container">
<SimpleBarReact style={{maxHeight: 680}} id="scroll-bar-cont">
<div className="messages-container" id="for-slider" >
<MessageFrom />
<MessageTo />
<div style={{ float:"left", clear: "both" }}
ref={el => {this.el=el;}}>
</div>
</div>
</SimpleBarReact>
<ChatInput />
</div>
);
}
}
export default Chat;
https://codesandbox.io/s/great-currying-x4m8m?file=/src/message-to.js
It works well. But It doesn't work in next level component.
I am having problems with navigating to a tab from another screen. When I am on the page clicking the tabs, the content switches fine, but when I try to set the active tab from another component before navigating to that screen, I am having issues with going to the specified tab.
I've tried passing parameters through the navigation to the parent screen like this: this.props.navigation.navigate('Menu', {goToOrderDetails: true}) and then inside the Menu screen, I made a componentFocused function where every time the page is in focus, I am checking if that goToOrderDetails parameter is true, and if it is, I am manually setting the state variable that is being used to set the active tab. This, however, is not working and just returns directly to the default tab (0), however, the styling color indicators are on the correct tab, but the content is that of the first tab.
This is how I am currently trying to do it:
Here is the Menu screen:
import React, {Component} from 'react';
import {observer} from "mobx-react";
import {ScrollView} from 'react-native';
import {Container, Tab, Tabs, ScrollableTab} from 'native-base';
import OrderHistory from './OrderHistory';
import Favorites from '../components/Favorites';
import Heading from '../components/Heading';
import store from '../store/store';
import i18n from 'i18n-js';
class Menu extends Component {
constructor() {
super();
this.subs;
this.state = {
activeTab: 0,
initialPage: 0
};
}
getTab() {
if(this.props.navigation.state.params){
if(this.props.navigation.state.params.page == 'orderhistory') {
return 2;
}if(this.props.page == 'favorites'){
return 1;
}else{
return 0;
}
} else {
if (this.props.navigation.getParam('orderHistory') || store.toOrderHistory == true) {
return 2;
} else if (this.props.navigation.getParam('favorites')) {
return 1;
}
store.toOrderHistory.set(false);
}
}
componentDidMount() {
this._componentFocused();
this._sub = this.props.navigation.addListener(
'didFocus',
this._componentFocused
);
}
_componentFocused = () => {
store.updateActiveTab(this.getTab());
}
updateTab(tab) {
store.updateActiveTab(tab.i);
}
render() {
return (
<Container>
<Heading title={'Menu'} />
<Tabs onChangeTab={(tab) => {this.updateTab.bind(this, tab)}}
page={store.activeTab.get()}
renderTabBar={()=> <ScrollableTab />}>
<Tab heading={i18n.t('menu.all_tab')}>
<ScrollView>
{this.displayMenu()}
</ScrollView>
</Tab>
<Tab heading={i18n.t('menu.fav_tab')}>
<Favorites></Favorites>
</Tab>
<Tab heading={i18n.t('menu.recent_tab')}>
<OrderHistory></OrderHistory>
</Tab>
</Tabs>
</Container>
)
};
}
export default observer(Menu);
And I am trying to send the navigation parameter from the order details screen to this screen like this: this.props.navigation.navigate('Menu',{goToOrderDetails: true}) and when that parameter is true, I am updating the store activeTab value like this: store.updateActiveTab.set(2).
The strangest part is that if I console.log the tab value, it is 2! Which is the correct one I need it to be on! And as I mentioned earlier, the color of the title is also the active color! It is just the content and the color underline that are not on that tab.
Is it possible that it is necessary to refresh the entire tabs component so that I can change the active tab from another screen? I am not sure why this behavior is occurring and could use some help!
Here is a screenshot of what happens after I have manually changed the active tab from the order details component!
I am also using same tab and implement as below:
<Tabs ref={(c) => { this.bottomTabRef = c; }} initialPage={0} page={pageNum} onChangeTab={({ from, i }) => { this.setState({ pageNum: i }); this.bottomTabRef.goToPage(0); }}>
<Tab heading="tab1">
<Text> Tab1 </Text>
</Tab>
<Tab heading="tab2">
<Text> Tab2 </Text>
</Tab>
</Tabs>
I am trying to create test cases for my application, providing source below:
import React, {Component} from 'react';
import {Tabs, Tab} from 'react-bootstrap';
import ManageUsers from './ManageUsers.jsx';
import ManageRoles from './ManageRoles.jsx';
import ManageUserGroups from './ManageUserGroups.jsx';
export default class UserManagement extends Component {
constructor(props) {
super(props);
this.handleSelect = this.handleSelect.bind(this);
this.state = {
selectedTab: 1
}
}
handleSelect(key){
this.setState({
selectedTab: key
});
}
render() {
return (
<div className="container listView">
<Tabs activeKey={this.state.selectedTab} onSelect={this.handleSelect} className="customNavTabsHorizontal" id="navUserMgmt">
<Tab eventKey={1} title={this.state.multiLangMsgs.MANAGE_USERS}>
<ManageUsers isSelected={this.state.selectedTab === 1 ? true : false} ></ManageUsers>
</Tab>
<Tab eventKey={2} title={this.state.multiLangMsgs.MANAGE_ROLES_PERMISSIONS}>
<ManageRoles isSelected={this.state.selectedTab === 2 ? true : false} ></ManageRoles>
</Tab>
<Tab eventKey={3} title={this.state.multiLangMsgs.MANAGE_USER_GROUPS}>
<ManageUserGroups isSelected={this.state.selectedTab === 3 ? true : false}></ManageUserGroups>
</Tab>
</Tabs>
</div>
);
}
}
and the test case is like this
import React from 'react';
import {shallow} from 'enzyme';
import UserManagement from './UserManagement.jsx';
describe('<UserManagement />', () => {
it('should handle selected tab state changes', () => {
const userMgmt = shallow(<UserManagement />);
const secondTab = userMgmt.find('Tab').at(0);
secondTab.simulate('click');
expect(userMgmt.state().selectedTab).toEqual(2);
});
});
When I run the npm test it always gets fail saying that expected is 2 but actual is 1. It seems it's not setting the state value. Can any one please help me out with this.
When you use shallow rendering, it renders only elements exactly from one render function you test. It doesn't know how to handle click on Tab.
To simultate your case, you have 2 option:
Render also children nodes using mount rendering, and simulate click on DOM node.
Call onSelect or simultate select on Tabs element.
Hello im trying to make an image changer. at first load i should get displayed the first image in the state. if click on the button the image should be changed to second and so on. the problem right now is get displayed both images with buttons
here is my bin : enter link description here
Because you display the 2 image in your renderer.
Heres an idea how to do it (with no animation, I dont know the CSSTransitionGroup component). Just replace your main.js code withthe following
import React from 'react'
import {render} from 'react-dom'
import { CSSTransitionGroup } from 'react-transition-group'
class FadeImage extends React.Component {
constructor(props) {
super(props);
this.state = {
images: [
'http://via.placeholder.com/350x150',
'http://via.placeholder.com/350x151'
],
currentImage: 0
};
}
fadeImage(e) {
e.preventDefault();
this.setState({currentImage: (this.state.currentImage + 1) % this.state.images.length})
}
render() {
return (
<div className="image">
<CSSTransitionGroup
transitionName="example"
transitionEnterTimeout={300}
transitionLeaveTimeout={300}
>
<section>
<button className="button" onClick={this.fadeImage.bind(this)}>Click!</button>
<img src={this.state.images[this.state.currentImage]}/></section>
</CSSTransitionGroup>
</div>
);
}
}
render(<FadeImage />, document.querySelector('#app'))
http://bl.ocks.org/piotrf/1b7b14b0c2bfbfe1f1ef this is almost exactly what you want. You can just get rid of the parts you dont need and change the buttons to the images you want