Ok, so. I am currently following this tutorial: https://www.freecodecamp.org/news/react-movie-app-tutorial/ . I have copied the code verbatim. I have installed bootstrap via the instructions on this website: https://react-bootstrap.github.io/getting-started/introduction#stylesheets . I have tried every configuration in every place of importing 'bootstrap/dist/css/bootstrap.min.css' including the <link>. The Row class is not working. Here is my Code...
import 'bootstrap/dist/css/bootstrap.min.css'
import './index.css'
import MovieList from "./components/MovieList"
const App = () => {
const [movies, setMovies] = useState([])
//const [favorite, setFavorite] = useState([])
//const [searchValue, setSearchValue] = useState("")
const getMovieRequest = (searchValue) => {
const url = `http://www.omdbapi.com/?s=jaws&apikey=76fd1ead`
fetch(url)
.then(resp => resp.json())
.then(data => {
if (data.Search) {
setMovies(data.Search)
}
})
}
useEffect(() => {
getMovieRequest()
}, [])
console.log(movies)
return (
<div className="container-fluid">
<div className="row">
<MovieList movies={movies} />
</div>
</div>
)
}
export default App;
import React from "react"
/*export default function MovieList(props) {
const displayMovies = props.movies.map(movie => {
return (
<div>
<img src={movie.Poster} alt="moive" />
</div>
)
})
return(
<>
{displayMovies}
</>
)
}*/
const MovieList = (props) => {
return (
<>
{props.movies.map((movie, index) => (
<div>
<img src={movie.Poster} alt="movie" ></img>
</div>
))}
</>
)
}
export default MovieList;
import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Any help would be greatly appreciated!
There is "bootstrap" itself and it is independent of what kind of framework you are using (React, Vue, Angular or just vanilla). It uses mostly css classes and jQuery for some functionality. Then there is "react-bootstrap", which is a complete re-write of bootstrap logic. It's written in React and offers a collection of components. That's why when you use react-bootstrap you only need the css part of bootstrap, but not the js/jQuery part.
Using only bootstrap?
npm i bootstrap
import 'bootstrap/dist/css/bootstrap.min.css' in your App.js or index.js
https://codesandbox.io/s/crazy-meninsky-9lmpmr?file=/src/App.js
Using react-bootstrap?
npm i react-bootstrap boostrap
import 'bootstrap/dist/css/bootstrap.min.css' in your App.js or index.js
https://codesandbox.io/s/serene-heisenberg-1xfvut
When you look into the both sandboxes you see that row is working either way.
Related
I am trying to find the most efficient way to add syntax highlighting to my react sanity.io blog. Here's the article component that I created using react:
import React, {useEffect, useState} from "react";
import {useParams} from "react-router-dom";
import sanityClient from "../../client";
import BlockContent from "#sanity/block-content-to-react";
import imageUrlBuilder from "#sanity/image-url";
import Prism from "prismjs";
const builder = imageUrlBuilder(sanityClient);
function urlFor(source) {
return builder.image(source);
}
const serializers = {
types: {
code: (props) => (
<pre data-language={props.node.language}>
<code>{props.node.code}</code>
</pre>
),
},
};
export default function SinglePost() {
const [postData, setPostData] = useState(null);
const {slug} = useParams();
useEffect(() => {
sanityClient
.fetch(
`*[slug.current == $slug]{
title,
slug,
mainImage{
asset->{
_id,
url
}
},
body,
"name": author->name,
"authorImage": author->image
}`,
{slug}
)
.then((data) => setPostData(data[0]))
.catch(console.error);
Prism.highlightAll();
}, [slug]);
if (!postData) return <div>Loading...</div>;
return (
<article>
<h2>{postData.title}</h2>
<div>
<img
src={urlFor(postData.authorImage).width(100).url()}
alt="Author is Kap"
/>
<h4>{postData.name}</h4>
</div>
<img src={urlFor(postData.mainImage).width(200).url()} alt="" />
<div>
<BlockContent
blocks={postData.body}
projectId={sanityClient.clientConfig.projectId}
dataset={sanityClient.clientConfig.dataset}
serializers={serializers}
/>
</div>
</article>
);
}
I am importing article data from Sanity and rendering it as a component. I tried using prism.js but I am having issues getting it to work.
What's the best and most efficient way to to enable syntax highlighting?
Well, I'd use react-syntax-highlighter package on NPM. It's pretty easy to add to your project. Basically a plug-and-play. With no awkward configurations.
I recently started working with React, and I'm trying to understand why my context.js is giving me so much trouble. Admittedly I'm not great with JavaScript to start, so I'd truly appreciate any insight.
Thank you, code and the error that it generates:
import React, { useState, useContext } from 'react';
const AppContext = React.createContext(undefined, undefined);
const AppProvider = ({ children }) => {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const openSidebar = () => {
setIsSidebarOpen(true);
};
const closeSidebar = () => {
setIsSidebarOpen(false);
};
const toggle = () => {
if (isSidebarOpen) {
closeSidebar();
} else {
openSidebar();
}
};
return (
<AppContext.Provider
value={{
isSidebarOpen,
openSidebar,
closeSidebar,
toggle
}}
>
{children}
</AppContext.Provider>
);
};
export const useGlobalContext = () => {
return useContext(AppContext);
};
export { AppContext, AppProvider };
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
Thank you again for taking the time to look!
EDIT: Sidebar App Added for context (double entendre!)
import React from 'react';
import logo from './logo.svg'
import {links} from './data'
import {FaTimes} from 'react-icons/fa'
import { useGlobalContext } from "./context";
const Sidebar = () => {
const { toggle, isSidebarOpen } = useGlobalContext();
return (
<aside className={`${isSidebarOpen ? 'sidebar show-sidebar' : 'sidebar'}`}>
<div className='sidebar-header'>
<img src={logo} className='logo' alt='NavTask Management'/>
<button className='close-btn' onClick={toggle}>
<FaTimes />
</button>
</div>
<ul className='links'>
{links.map((link) => {
const { id, url, text, icon } = link;
return (
<li key={id}>
<a href={url}>
{icon}
{text}
</a>
</li>
);
})}
</ul>
</aside>
);
};
export default Sidebar;
EDIT: I imported something wrong :facepalm:
Let me first run down what code ive written to get this output then I will tell you the expected output and what im confused about
App.jsx
import React from "react";
import Home from "./components/pages/HomePage";
import store from "./ducks/store";
import { Provider } from "react-redux";
import { BrowserRouter, Route, Switch } from "react-router-dom";
const App = () => {
return (
<BrowserRouter>
<Provider store={store}>
<Switch>
<Route exact path="/" component={Home} />
</Switch>
</Provider>
</BrowserRouter>
);
};
export default App;
Home.jsx
import React, { useEffect } from "react";
import FlexBox from "../../shared/FlexBox";
import BlogPostList from "./SortSettings";
import { useSelector, useDispatch } from "react-redux";
import { fetchAllBlogs } from "../../../ducks/blogs";
import {
getBlogData,
getBlogPosts,
getBlogTags,
} from "../../../ducks/selectors";
import SpinLoader from "../../shared/SpinLoader";
const Home = () => {
const blogData = useSelector((state) => getBlogData(state));
const blogPosts = useSelector((state) => getBlogPosts(state));
const blogTags = useSelector((state) => getBlogTags(state));
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAllBlogs());
}, [dispatch]);
// TODO: handle if blogData.requestError comes back as true
if (blogData.isLoading || !blogPosts || !blogTags) {
return (
<FlexBox
alignItems="center"
justifyItems="center"
width="100vw"
height="100vh"
>
<SpinLoader />
</FlexBox>
);
}
return (
<FlexBox height="100vh" width="100vw">
<BlogPostList blogPosts={blogPosts} />
</FlexBox>
);
};
export default Home;
BlogPostList.jsx
import React from "react";
import BlogPost from "./BlogPost";
import FlexBox from "../../shared/FlexBox";
const BlogPostList = ({ blogPosts }) => {
return (
<FlexBox flexDirection="column">
Why in the world is this rendering a SortSettings component AHHHHHH!
</FlexBox>
);
};
export default BlogPostList;
Now my question is this why is it that the Home component is rendering a component as showed here https://gyazo.com/8cac1b28bdf72de9010b0b16185943bb what I would expect the Home component to be rendering is a BlogPostList if anyone has an idea help would be appreciated ive been stuck on this for awhile now (im pretty new so this might just be a noob mistake so sorry if its something obvious)
I'm rendering components from my external (node_modules) pattern library. In my main App, I'm passing my Link instance from react-router-dom into my external libraries' component like so:
import { Link } from 'react-router-dom';
import { Heading } from 'my-external-library';
const articleWithLinkProps = {
url: `/article/${article.slug}`,
routerLink: Link,
};
<Heading withLinkProps={articleWithLinkProps} />
In my library, it's rendering the Link as so:
const RouterLink = withLinkProps.routerLink;
<RouterLink
to={withLinkProps.url}
>
{props.children}
</RouterLink>
The RouterLink seems to render correctly, and even navigates to the URL when clicked.
My issue is that the RouterLink seems to have detached from my App's react-router-dom instance. When I click Heading, it "hard" navigates, posting-back the page rather than routing there seamlessly as Link normally would.
I'm not sure what to try at this point to allow it to navigate seamlessly. Any help or advice would be appreciated, thank you in advance.
Edit: Showing how my Router is set up.
import React from 'react';
import { hydrate, unmountComponentAtNode } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { ConnectedRouter } from 'react-router-redux';
import RedBox from 'redbox-react';
import { Route } from 'react-router-dom';
import { Frontload } from 'react-frontload';
import App from './containers/App';
import configureStore from './redux/store';
import withTracker from './withTracker';
// Get initial state from server-side rendering
const initialState = window.__INITIAL_STATE__;
const history = createBrowserHistory();
const store = configureStore(history, initialState);
const mountNode = document.getElementById('react-view');
const noServerRender = window.__noServerRender__;
if (process.env.NODE_ENV !== 'production') {
console.log(`[react-frontload] server rendering configured ${noServerRender ? 'off' : 'on'}`);
}
const renderApp = () =>
hydrate(
<AppContainer errorReporter={({ error }) => <RedBox error={error} />}>
<Provider store={store}>
<Frontload noServerRender={window.__noServerRender__}>
<ConnectedRouter onUpdate={() => window.scrollTo(0, 0)} history={history}>
<Route
component={withTracker(() => (
<App noServerRender={noServerRender} />
))}
/>
</ConnectedRouter>
</Frontload>
</Provider>
</AppContainer>,
mountNode,
);
// Enable hot reload by react-hot-loader
if (module.hot) {
const reRenderApp = () => {
try {
renderApp();
} catch (error) {
hydrate(<RedBox error={error} />, mountNode);
}
};
module.hot.accept('./containers/App', () => {
setImmediate(() => {
// Preventing the hot reloading error from react-router
unmountComponentAtNode(mountNode);
reRenderApp();
});
});
}
renderApp();
I've reconstructed your use case in codesandbox.io and the "transition" works fine. So maybe checking out my implementation might help you. However, I replaced the library import by a file import, so I don't know if that's the decisive factor of why it doesn't work without a whole page reload.
By the way, what do you mean exactly by "seamlessly"? Are there elements that stay on every page and should not be reloaded again when clicking on the link? This is like I implemented it in the sandbox where a static picture stays at the top on every page.
Check out the sandbox.
This is the example.js file
// This sandbox is realted to this post https://stackoverflow.com/q/59630138/965548
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Heading } from "./my-external-library.js";
export default function App() {
return (
<div>
<img
alt="flower from shutterstock"
src="https://image.shutterstock.com/image-photo/pink-flowers-blossom-on-blue-600w-1439541782.jpg"
/>
<Router>
<Route exact={true} path="/" render={Welcome} />
<Route path="/article/coolArticle" component={CoolArticleComponent} />
</Router>
</div>
);
}
const Welcome = () => {
const articleWithLinkProps = {
url: `/article/coolArticle`,
routerLink: Link
};
return (
<div>
<h1>This is a super fancy homepage ;)</h1>
<Heading withLinkProps={articleWithLinkProps} />
</div>
);
};
const CoolArticleComponent = () => (
<div>
<p>This is a handcrafted article component.</p>
<Link to="/">Back</Link>
</div>
);
And this is the my-external-library.js file:
import React from "react";
export const Heading = ({ withLinkProps }) => {
const RouterLink = withLinkProps.routerLink;
return <RouterLink to={withLinkProps.url}>Superlink</RouterLink>;
};
I have recently installed Material UI into my Meteor application using npm install --save material ui
I have gotten the <Header /> component showing up in my app.js file, but whenever I add other components, localhost:3000 simply displays a blank page. Please see my code below:
header.js
import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
class Header extends Component {
render() {
return(
<AppBar
title="Header"
titleStyle={{textAlign: "center"}}
showMenuIconButton={false}
/>
);
}
}
export default Header;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
THE ABOVE CODE WORKS WELL (see screenshot below)
However, if I add another component I get a blank screen
header.js is the same
new_post.js
import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
class NewPost extends Component {
render() {
return (
<TextField
hintText="Full width"
fullWidth={true}
/>
);
}
}
export default NewPost;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
<NewPost />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
The result is simply a blank screen
Why does adding one more component (<NewPost />)inside of <MuiThemeProvider> result in a blank screen? I referred to the material-ui documentation and their sample projects but their application structure is not similar to mine. Any advice? Please let me know if you need more info to make this question clearer.
Wow very strange but I managed to get it working by simply adding a <div>
app.js
const App = () => {
return (
<MuiThemeProvider muiTheme={getMuiTheme()}>
<div>
<Header />
<NewPost />
</div>
</MuiThemeProvider>
);
}
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
I would really appreciate if anyone could explain why adding a div makes this all work. Thank you!
I would really appreciate if anyone could explain why adding a div
makes this all work
If you look at the browser warning, "Invalid prop children of type array supplied to MuiThemeProvider, expected a single ReactElement.".
So, when you add a <div/> around your components, it wraps them together and turns them into a single react element.
MuiThemeProvider renders as null so you have to wrap children do anything - for example React.Fragment