i got trouble making a search function in react, not the function itself but how it redirecting. before i've tried using redirect and it doesn't load the parent component. no solution, then i changes the logic using Link to instead of redirect to. now the problem is the child component doesnt re-render and the only thing changes is the url.
Here is the complete code.
Child component:
class Search extends Component {
state = {
products: [],
count: '',
}
componentDidMount() {
window.scrollTo(0, 0)
const { match: { params } } = this.props;
axios.get('http://localhost:8000/api/v1/cari/' + params.userId)
.then(response => {
this.setState({ products: response.data.data, count: response.data.jumlah });
})
}
componentWillReceiveProps(props) {
this.forceUpdate();
this.setState({ diCari: this.state.diCari });
}
render() {
var jumlah = <div className="judul cari">Menampilkan {this.state.count} Produk</div>;
var { products } = this.state;
var hasil = products.map(products => {
<div className="kotakproduk produkcari" />
})
return (
<div>
<div className="gambarproduk">
<img src="https://www.mobiledokan.co/wp-content/uploads/2019/09/Xiaomi-Mi-9-Pro-Dream-White.jpg" />
</div>
<div className="nama">
{products.merk} {products.tipe}
</div>
<div className="harga">
<NumberFormat value={products.harga} displayType={'text'} thousandSeparator={true} prefix={'Rp. '} />
</div>
</div>
)
}
}
Parent component
class Master extends Component {
state = {
cari: '',
diCari: false
};
handleChange1 = (e) => {
this.setState({
cari: e.target.value
})
}
render() {
return (
<div>
<div className="header">
<Link to="/home">
<div className="logo">
<img src="/img/tokopon2.png" />
</div>
</Link>
<input type="text" name="search" placeholder="Search.." onChange={this.handleChange1} />
<Link to={"/search/" + this.state.cari}><button type="submit"><i className="fa fa-search"></i></button></Link>
<div className="login-button">
<Link to="/login">Login</Link>
<div className="keranjang-mobile">
<a href="#">
<span className="glyphicon glyphicon-shopping-cart"></span>
</a>
</div>
<div className="keranjang">
<a href="#" className="btn btn-info btn-lg">
<span className="glyphicon glyphicon-shopping-cart"></span> Keranjang Belanja
</a>
</div>
</div>
</div>
</div>
)
}
}
i already tried history.push still no changes
Related
When clicked close button code detects in the console that the component want's to be hidden but when I want to open the modal window by clicking the Logic or Signup button in navigation.js file those buttons don't detect any activity to the console.
This where I'm got the tutorial on how to do the modal widow but tried to work out for my need's --> https://alligator.io/react/modal-component/
Modal Window Component:
import React from 'react';
const Modal = ({ show, children }) => {
const showHideClassName = show ? 'modal display-block' : 'modal display-none';
return (
<div className={showHideClassName}>
<section className='modal-main'>
{children}
</section>
</div>
);
};
class App extends React.Component {
state = { show: false }
showSignup = () => {
this.setState({ show: true });
console.log('I was triggered during componentDidMount')
}
showLogin = () => {
this.setState({ show: true });
console.log('Fuck this not show the login form')
}
hideModal = () => {
this.setState({ show: false });
console.log('Yeah its hide the login and signup form')
}
render() {
return (
<div>
<Modal show={this.state.show} handleclose={this.hideModal} >
<div className="blkOverlay">
{/* This is Login Form to log in to your profile */ }
<div className="formContent modal-main">
<button className="closebtn" onClick={this.hideModal}>Close </button>
<h2>Welcome Back <span>Brandon!</span></h2>
<form data-show={this.state.show.toString()}>
<input type="text" name="email" placeholder="Email Address" />
<input name="password" type="text" placeholder="Password" />
<div className="passContent">
<div className="checkingPass">
<input className="inline" type="checkbox" name="check" value="Remember Password"/>
<span className="inline">Remember Password</span>
</div>
<p className="passFont">Forgot Password</p>
</div>
<input className="formmbtn" type="button" name="button" value="Login"/>
<div className="social-media-button">
<input className="clearbtn" type="button" name="button" value="Sign in with Facebook"/>
<div className="divider"/>
<input className="clearbtn" type="button" name="button" value="Sign in with Facebook"/>
</div>
<p className="passFont">Don't have an account? <span>Sign up</span></p>
</form>
</div>
{/* This is Sign up to create a account */}
</div>
</Modal>
</div>
)
}
}
export default App;
Navigation Component (Where the buttons are at to call the modal window to appear on click)
import React from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import Dropdown from "../components//pages/dropdowns/dropdowns.js";
import "../components/pages/SignupModal/signupmodal.js";
import hamburger from "../images/menu.svg";
class Navigation extends React.Component {
constructor(props) {
super(props);
this.state = {
isExpanded: false
};
}
handleToggle(e) {
e.preventDefault();
this.setState(prevState => ({
isExpanded: !prevState.isExpanded, // negate the previous expanded state
}));
}
render() {
const { isExpanded } = this.state;
return (
<Router>
<div className="NavbarContainer">
<div className="mobilecontainer LeftNav">
<h2 className="BrandName LeftNav mobileboxmenu inline FarRight">Kommonplaces</h2>
<div className="hamburger inlinev" >
<img
onClick={e => this.handleToggle(e)}
alt="menubtn"
src={hamburger}
/>
</div>
</div>
<ul className={`NavBar collapsed ${isExpanded ? "is-expanded" : ""}`}>
<Dropdown/>
<li className="RightNav"><Link to="/">Host Your Space</Link></li>
<li className="RightNav"><Link to="/">About Us</Link></li>
<li className="RightNav"><Link to="/">Contact Us</Link></li>
<div className="btnflexright">
<button className="RightNav"><Link onClick={ this.showSignup } to="/">Sign Up</Link></button>
<button className="RightNav"><Link onClick={ this.showLogin } to="/">Login</Link></button>
</div>
</ul>
</div>
</Router>
);
}
}
export default Navigation;
Any, helpful tips and advice would help, please.
That's because you placed the onClick event in the Link rather than on the button component. Change to the code below:
<div className="btnflexright">
<button className="RightNav" onClick={ this.showSignup }>
<Link to="/">Sign Up</Link>
</button>
<button className="RightNav" onClick={ this.showLogin }>
<Link to="/">Login</Link>
</button>
</div>
I use twitter API with Javascript API for websistes. When I click on anchor tag which should me redirect to /twitter/explore from /twitter I'm redirected to /twitter/explore but immediately back me to /twitter which is Twitter component. I got this error in chrome console:
Warning: Can’t perform a React state update on an unmounted component. This is a no-op, but
it indicates a memory leak in your application. To fix, cancel all subscriptions and
asynchronous tasks in the componentWillUnmount method twitter api.
I try resolve this problem by add global variable and call setState only when that variable is true and later when component is unmounting I change variable to false. Error does not exist but still the app redirect me back to /twitter. I can't render TwitterExplore component because back me. I'm not sure that this solution with global variable is good idea.
Here is my code below:
Twitter component with mapping /twitter
class Twitter extends React.Component {
isMountedTwitter = false;
constructor(props) {
super(props);
this.state = {
accessToken: '',
email: '',
name: '',
userID: '',
pictureUrl: '',
providerId: '',
screenName: '',
tokenSecret: ''
}
this.Auth = new AuthService();
}
componentDidMount() {
this.isMountedTwitter = true;
this.isMountedTwitter && window.twttr.widgets.load(document.getElementsByClassName("feed-container")[0]);
let jwtToken = null;
if(this.Auth.getTwitterToken() !== null) {
jwtToken = this.Auth.getTwitterToken();
}
if(this.Auth.getToken() !== null) {
jwtToken = this.Auth.getToken();
}
fetch(`/getuserdata/${jwtToken}`, {
method: 'GET',
headers: {
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(jsonData => {
if(this.isMountedTwitter) {
this.setState({
accessToken: jsonData.accessToken,
email: jsonData.email,
name: jsonData.name,
userID: jsonData.userID,
pictureUrl: jsonData.pictureUrl,
providerId: jsonData.providerId,
screenName: jsonData.screenName,
tokenSecret: jsonData.tokenSecret
}, () => {
window.twttr.widgets.createTimeline(
{
sourceType: 'likes',
screenName: this.state.screenName
},
document.getElementsByClassName("tweets-likes-container")[0],
{
width: '100%',
height: '100%',
related: 'twitterdev,twitterapi'
});
});
}
});
}
componentWillUnmount() {
this.isMountedTwitter = false;
}
render() {
return (
<div className="twitter-container">
<div className="twitter-grid-container">
<div className="twitter-grid-item-1">
<div className="twitter-left-categories-container">
<div className="twitter-profil-container">
{ this.state.name }
</div>
<TwitterCategoriesCard
pictureUrl={this.state.pictureUrl}
screenName={this.state.screenName}
/>
</div>
</div>
<div className="feed-container">
{/* <div className="twitter-user-profil">
<div className="twitter-header-profile">
</div>
<div className="tweets-profile-container">
</div>
</div> */}
<div className="tweets-likes-container">
</div>
</div>
<div className="twitter-grid-item-3">
<div className="twitter-rl-container">
<div className="twitter-groups-container">
<SearchTwitterPeople />
<AvailableTrends />
</div>
</div>
<div className="twitter-rr-container">
<div className="twitter-friends-container"></div>
</div>
</div>
</div>
</div>
);
}
}
export default withAuth(Twitter);
TwitterCategoriesCard component
class TwitterCategoriesCard extends React.Component {
constructor(props) {
super(props);
this.onExploreClick = this.onExploreClick.bind(this);
}
onExploreClick() {
this.props.history.push("/twitter/explore");
}
render() {
return (
<div className="twitter-categories-container">
<ul className="list-group twitter-categories-list">
<li className="list-group-item list-group-item-hover">
<div className="twitter-categories-icons-box">
<i className="fas fa-home"></i> Home
</div>
</li>
<li onClick={this.onExploreClick} className="list-group-item list-group-item-hover">
<div className="twitter-categories-icons-box">
<span style={{ fontWeight: '900' }}>#</span> Explore
</div>
</li>
<li className="list-group-item list-group-item-hover">
<div className="twitter-categories-icons-box">
<i className="fas fa-clock"></i> Timeline likes
</div>
</li>
<li className="list-group-item list-group-item-hover">
<div className="twitter-categories-icons-box">
<i className="fas fa-bell"></i> Notifications
</div>
</li>
<li className="list-group-item list-group-item-hover">
<div className="twitter-categories-icons-box">
<i className="far fa-envelope"></i> Messages
</div>
</li>
<li
className="list-group-item list-group-item-hover"
>
<div className="twitter-categories-icons-box">
<img
src={this.props.pictureUrl}
alt="Avatar"
className="twitter-categories-avatar"
/> Profile
</div>
</li>
<li className="list-group-item list-group-item-hover add-tweet-button">
<a
className="twitter-share-button"
href="https://twitter.com/intent/tweet"
data-size="large"
>
Tweet
</a>
</li>
</ul>
</div>
);
}
}
export default withRouter(TwitterCategoriesCard);
withAuth HOC:
export default function withAuth(AuthComponent) {
const Auth = new AuthService();
let customAuthComponent = false;
class AuthWrapped extends React.Component {
componentDidMount() {
customAuthComponent = true;
if(!Auth.loggedIn()) {
this.props.history.replace("/login");
} else {
let twitterJwtToken = Auth.getTwitterToken();
let facebookJwtToken = Auth.getToken();
try {
if(twitterJwtToken) {
customAuthComponent && this.props.history.replace("/twitter");
}
if(facebookJwtToken) {
customAuthComponent && this.props.history.replace("/dashboard");
}
} catch(err) {
if(twitterJwtToken) {
Auth.logoutTwitter();
}
if(facebookJwtToken) {
Auth.logout();
}
this.props.history.replace("/login");
}
}
}
componentWillUnmount() {
customAuthComponent = false;
}
render() {
if(Auth.loggedIn()) {
return (
customAuthComponent && <AuthComponent history={this.props.history} />
);
} else {
return null;
}
}
}
return AuthWrapped;
}
App.js
function App() {
return (
<Provider store={store} >
<Router>
<div className="App">
<I18nextProvider i18n={i18next}>
<Header />
<Route exact path="/settings" component={Settings} />
<Route exact path="/twitter" component={Twitter} />
<Route exact path="/twitter/explore" component={TwitterExplore} />
</I18nextProvider>
</div>
</Router>
</Provider>
);
}
export default App;
I have the main component DisplayLinks.js. In this component, while clicking on a link, I want to display a table with it in the same page. My second component is StudentListTable, in which I am adding a table with props. It doesn't show, why?
I have added my sample code here:
state = {
visible: false,
showTable:false
}
showCourseModal = () => {
this.setState({
visible: true,
});
}
showStudentList = () => {
this.setState({
showtable: true,
})
}
render() {
return (
<div align="center">
<a href="#" onClick={this.showCourseModal}>Course</a>
<a href="#" onClick={this.showStudentList}>StudentList</a>
<CourseModal
visible={this.state.visible}
onOk={this.onOk}
onCancel={this.onCancel} />
<StudentListtable showtable={this.state.showTable} data={data}/>
</div>
)
}
Second component:
state = {
showTable: this.props.showTable,
}
render() {
return (
<div>
<div align="right">
<Button
type="primary">Update</Button>
</div>
<Table
dataSource={this.props.data}
showTable={this.props.showTable}
columns={columns}
pagination={{ pageSize: 5 }}
/>
</div>
)
}
You can handle it by conditioning the inner component in the render this way:
render() {
return (
<div align="center">
<a href="#" onClick={this.showCourseModal}>Course</a>
<a href="#" onClick={this.showStudentList}>StudentList</a>
<CourseModal
visible={this.state.visible}
onOk={this.onOk}
onCancel={this.onCancel} />
{
this.state.showTable?
<StudentListtable data={data}/>
:
<p>No tables to show</p>
}
</div>
)
}
The toaster component is made programatically and i am passing the message through another component.
my Toaster component Looks like this:-
export default class MyToaster extends React.Component {
constructor(props) {
super(props);
this.toaster = React.createRef();
this.state = {
message: [],
show: false
};
this.state.message = this.props.message;
}
handleClose() {
this.setState({show: false})
}
createtoaster() {
let toastmessage = [];
if ( this.state.show === true) {
for (let i = 0; i <= this.state.message.length; i++) {
let tmessage = <div className="col-md-3 offset-md-8">
<div className="card-header">
<h3 className="card-title">Toast</h3>
</div>
<div className="card-body">
{this.state.message[i]}
</div>
<div className="card-footer">
<button className="btn btn-primary" onClick={this.handleClose()}>x</button>
</div>
</div>
toastmessage.push(tmessage);
}
return (toastmessage);
}
}
render() {
return (
<div className="col-md-2 offset-md-9">
<button className="btn btn-primary" onClick={() => this.setState({show:true})}>show Toaster</button>
</div>
)
}
}
Also this is my PostCard.js page in which the toaster component is called and message is passed.
export default class MyCard extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPage: this.props.pgNo,
details: [],
id: null,
index: 0
}
this.message = 'osihfosihfoi';
}
AddButton() {
return (
<Link to={`${this.props.url}/addnew${this.props.url}`}>
<button
style={{
float: "right"
}}
className="btn btn-primary"><Faplus/>
</button>
</Link>
);
}
closeAfter7 = () => toast("7 Kingdoms", {autoClose: 7000});
fetchMoreData = () => {
if(this.state.index<100){
this.setState({
index: this.state.index + 5
})
}}
componentDidMount() {
window.addEventListener('scroll', this.onScroll);
this.fetchMoreData();
}
onScroll = () => {
$(window).scroll(() => {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
this.fetchMoreData();
}
});
}
createCard = () => {
let cardBody = [];
for (let i = this.state.currentPage; i < this.state.index; i++) {
let card = <div className="content">
<div className="container-fluid">
<div className="col-md-6 offset-md-3">
<div className="card">
<div className="card-header">
<h3 className="card-title"></h3>
</div>
<div className="card-body">
<h5>
ID :
</h5>{this.props.data[i].id}<br/>
<h5>
User ID :
</h5>{this.props.data[i].userId}<br/>
<h5>
Title :
</h5>{this.props.data[i].title}<br/>
<h5>
Body :
</h5>{this.props.data[i].body}<br/>
</div>
<div className="card-footer clearfix"></div>
</div>
</div>
</div>
</div>
cardBody.push(card);
}
return (cardBody)
}
render() {
return (
<div className="row">
<div className="col-md-2 offset-md-10">{this.AddButton()}
</div>
<Toaster message={this.message}/>
{/* <div id="snackbar" style={{backgroundColor: "red"}}>Hogaya.</div> */}
<div>
{this.createCard()}
</div>
</div>
)
}
}
My UI renders the Show toaster button but not do anything when it is clicked. Also it dosent give any errors. Can't figure out the problem so if anyone can point out what i am doing wrong it ll be great. Also Please let me know if I am not using the correct method or logic.
TIA.
It was not rendering anything because I wasn't rendering my createtoaster component. the correct way is that in my toaster component i should render it like this
render() {
return (
<div className="col-md-2 offset-md-9">
<button className="btn btn-primary" onClick={this.handleOpen}></button>
{this.createtoaster()}
</div>
)
}
}
I started playing with some React/Redux + t7 (in order to avoid any sort of transpiling), for the sake of learning.
When it all started making some sense to me, I encountered this voodooish issue, where the bounded onClick function sometimes fires and sometimes doesn't (?!)
As you can see, clicking the plus button doesn't always invoke the bounded function to onClick.
I'm using the latest version of Google Chrome (v53).
What the hell?
JS
'use strict';
const store = Redux.createStore(Redux.combineReducers({
todos: (state = [], action) => {
switch(action.type) {
case 'ADD_TODO':
return state.concat([action.payload]);
default:
return [];
}
}
}));
t7.module((t7) => {
t7.assign("AddTodo", React.createClass({
addTodo() {
console.log('clicked');
return store.dispatch({
type: 'ADD_TODO',
payload: {
text: this.refs.todoText.value,
}
})
},
render() {
return t7`
<div className="row">
<div className="col-xs-4 form-group-lg">
<input className="form-control" ref="todoText"/>
</div>
<div className="col-xs-2">
<button className="btn btn-lg btn-info">
<span className="glyphicon glyphicon-plus"
onClick="${this.addTodo}"
style=${{fontSize: 'large'}}>
</span>
</button>
</div>
</div>
`;
}
}));
t7.assign("TodoList", React.createClass({
render() {
return t7`
<div className="row">
<div className="col-xs-12">
<ul>
${store.getState().todos.map((todo, i) => t7`
<li key=${i}>${todo.text}</li>
`)}
</ul>
</div>
<div>
`;
}
}));
const render = () => ReactDOM.render(
t7`
<div className="container">
<div className="jumbotron">
<h1>Todos</h1>
</div>
<AddTodo />
<TodoList />
</div>
`, document.getElementById('root')
);
store.subscribe(render);
render();
});
Your Click event works whenver your click on the glyphicon plus and not outside it. The issue is that you have placed the onClick event at the wrong place add it to the button rather than the span and it will work
render() {
return t7`
<div className="row">
<div className="col-xs-4 form-group-lg">
<input className="form-control" ref="todoText"/>
</div>
<div className="col-xs-2">
<button className="btn btn-lg btn-info" onClick="${this.addTodo}">
<span className="glyphicon glyphicon-plus"
style=${{fontSize: 'large'}}>
</span>
</button>
</div>
</div>
`;
}