Excalidraw react component with Collaboration feature - javascript

I have created an component in a react app with a drawing canvas with excalidraw
I did the following steps to implement excalidraw.
1.npm i #excalidraw/excalidraw
2.Created a component named excalidrawComponent.js with following code
import { useState, useEffect } from "react";
export default function Excalidraw(props) {
const [Comp, setComp] = useState(null);
useEffect(() => {
import("#excalidraw/excalidraw").then((comp) => setComp(comp.Excalidraw));
}, []);
return <>
<div className="excalidraw-component">
{Comp && <Comp />}
</div>
</>
}
But I am not able to find the collaborate functionality what we can see in excalidraw statdalone project.
You can find below images to check diffrences.
[standalone excalidraw](https://i.stack.imgur.com/DGtLT.png)
[My react application with excalidraw darwing tool]https://i.stack.imgur.com/IVHEq.png)
I need a live collaboration button on top and its feature.
How to achieve this.
Thanks in advance.

Related

React Router 6 - useLocation Not Working Like I Expected [duplicate]

This question already has an answer here:
How to run a function when user clicks the back button, in React.js?
(1 answer)
Closed 5 months ago.
I'm new to React, so I'm sure I'm not understanding the use cases for useLocation - like what it is good for and what it is not intended for.
I'd like to have a method that a specific component can be aware of any location change included those from pushState. Note: I'm converting an Anuglar JS 1.0 code base that just used all query info in the hash. I'd like to use pushState browser feature in this rewrite.
Sample code below (I just have it as the single component in a new React app component:
import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
const RandLocation: React.FC = () => {
const location = useLocation();
useEffect(() => {
console.log('location: ', location);
}, [location]);
return (
<div>
<button
onClick={() => {const r = Math.random(); window.history.pushState({'rnd': r }, '', '/?rnd=' + r)}}>
Click Me</button>
<br/>
</div>
)
}
export default RandLocation;
I only see the useEffect run on load, and if I move forward or back using the browser buttons. But not when I click the "Click Me" button. What am I missing? Id like to keep this "awareness of location" as simple as possible within the React frontend code. Like is there a technique that works in apps regardless of if you have React Router routes defined?
I am using React version 17.0.2 and react-router-dom version 6.2.2
I think because the window.history.pushState call is outside of React's state management it react-router won't be aware of it. There used to be a way to listen for these events, but I'm not sure something equivalent exist in React Router 6.
You could use the useNavigate hook. Maybe something like:
import React, { useEffect } from "react";
import { useLocation, useNavigate } from "react-router-dom";
const RandLocation = () => {
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
console.log("location: ", location);
}, [location]);
return (
<div>
<button
onClick={() => {
const r = Math.random();
//window.history.pushState({ rnd: r }, "", "/?rnd=" + r);
navigate("/?rnd=" + r, { state: { rnd: r } });
}}
>
Click Me
</button>
<br />
</div>
);
};
export default RandLocation;
One issue with this approach, is you'd have to set up a default route to catch anything that no route is defined for like this:
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="*" element={<WhereYouWantDefaultRoutesToGoTo />} />
</Routes>
</BrowserRouter>
You might also want to take a look at: https://stackoverflow.com/a/70095819/122201

Giphy React Grid component is not working

I am trying to replicate the search and masonry grid from the official documentation using their Codesandbox example.
However, when I am trying to use it, the code is not returning any gifs back.
I have verified that the JS fetch is indeed returning back gifs, it seems that the grid is not calling the fetchGifs function.
I am hitting the same issue with Carousel component as well.
Can anyone help me with this issue?
Codesandbox link for my implementation - https://codesandbox.io/s/cocky-waterfall-ny9rzk
Component i was trying to use - Search and Grid from https://github.com/Giphy/giphy-js/tree/master/packages/react-components
import { GiphyFetch } from "#giphy/js-fetch-api";
import { Grid } from "#giphy/react-components";
import useDebounce from "react-use/lib/useDebounce";
import React, { useState } from "react";
export default function App() {
const giphyFetch = new GiphyFetch("PZpYG85wQpugMlEx02GGqeKfKZ8eMdFZ");
const [debouncedInput, setDebouncedInput] = useState<string>("");
const [term, setTerm] = useState<string>("");
useDebounce(() => setTerm(debouncedInput), 500, [debouncedInput]);
const NoResults = <div className="no-results">No Results for {term}</div>;
const fetchGifs = (offset: number) => {
return giphyFetch.search(term, { offset, limit: 10 });
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<input
placeholder="type to search"
onChange={({ target: { value } }) => setDebouncedInput(value)}
value={debouncedInput}
/>
<Grid
key={term}
columns={3}
gutter={6}
noResultsMessage={NoResults}
width={400}
fetchGifs={fetchGifs}
/>
</div>
);
}
Try removing strict mode here:
https://codesandbox.io/s/cocky-waterfall-ny9rzk?file=/src/index.tsx
I guess the Grid is incompatible with React 18, possibly due to the useEffect change it brings.
Alternatively you could use React 17.x
Updated looks like they've introduced a fix
https://github.com/Giphy/giphy-js/commit/dade2aa10442c9ca8e6741125071dc1053e89181

Why when following the quick start for easy peasy is my state not changing in Nextjs?

I was trying to use easy peasy for global state management within a nextjs app and was running into problems where the state would only update when I changed pages. I thought maybe I didn't quite grasp what I was doing so I decided to try a quick app with the quick start guide: https://easy-peasy.vercel.app/docs/tutorials/quick-start.html
Setting all this up nothing is happening when I click the button. If I make a change within the code and save it then all the changes happen when it hot reloads.
Does anyone have any idea why this is and how I fix it? I thought it might be nextjs but I just tested it with react and that's not working either. I must be missing some understanding of how this is supposed to work. In a tutorial I was following it worked just fine and cloning it also works. I have no idea when I try and create my own project with the same code its why it's not updating right away.
edit: I don't know why I didn't just share the repo. Here it is: https://github.com/Kyle-Kroger/easy-peasy-broken
edit 2: I tried to get Traversy Media's easy-peasy tutorial to work updating things for v5 and that does the same thing. Nothing updates when clicked but if I edit the code it will update the state on reload. I'm going to try on another computer in the morning.
https://github.com/Kyle-Kroger/traversy-media-easy-peasy-broken
edit 3: I think I might have figured it out. I wonder if it has something to do with version 18 of react. That is the only thing that is different between the repo I cloned that works and mine. Going to see how to use create-react-app with an older version and see if that will work.
edit 4: Well after many hours I figured out the problem. Something in react version 18 broke something with how easy-peasy works. Going back to 17 makes things work.
Here is all my code:
//store.js
import { createStore, action } from "easy-peasy";
export const store = createStore({
todos: [],
addTodo: action((state, payload) => {
state.todos.push({ text: payload, done: false });
}),
});
//body.js
import { useStoreState } from "easy-peasy";
const Body = () => {
const todos = useStoreState((state) => state.todos);
return (
<>
<p onClick={() => console.log(todos)}>Some more text to click</p>
<ul>
{todos.map((todo) => (
<li key={todo.text}>{todo.text}</li>
))}
</ul>
</>
);
};
export default Body;
//title.js
import { useStoreActions } from "easy-peasy";
import { useState } from "react";
const Title = () => {
const addTodo = useStoreActions((actions) => actions.addTodo);
const [value, setValue] = useState("");
return (
<>
<input onChange={(e) => setValue(e.target.value)} value={value} />
<button onClick={() => addTodo(value)}>Add Todo</button>
</>
);
};
export default Title;
_app.js
import "../styles/globals.css";
import { StoreProvider } from "easy-peasy";
import { store } from "../lib/store";
function MyApp({ Component, pageProps }) {
return (
<StoreProvider store={store}>
<Component {...pageProps} />
</StoreProvider>
);
}
export default MyApp;
//index.js
import Body from "../components/body";
import Title from "../components/title";
export default function Home() {
return (
<div>
<Title></Title>
<Body></Body>
</div>
);
}
Removing
<React.StrictMode></React.StrictMode>
from index.js fixes the issue on React 18.
Not a real solution but a workaround till Someone fixes it.
I was also having trouble with the update. Interestingly, I changed the StoreProvider from index.js to app.js and it works.

Issue in using useFocusEffect inside function component

I am trying to use "useFocusEffect" inside a functional component and getting the following error:
Couldn't find a navigation object. Is your component inside a screen.
I am using the following approach
useFocusEffect(
React.useCallback(() => {
console.log("Salil RenderFeedContent useFocusEffect ")
}, [])
);
My Component :
export default RenderFeedContent = (props) => {
useFocusEffect(
React.useCallback(() => {
console.log('Salil useFocusEffect RenderFeedContent')
}, [])
);
//Rest of the logic is to render the component .
Code from where the component is getting rendered . This is class based component and I have access to the navigation prop till this point:
const FeedPost=props=>{
const { navigation } = props
return(
<RenderFeedContent {...props} navigation = {navigation} content={props.content} />
)
}
Please refer to following link for all details
Versions:
#react-navigation/native: 5.7.3
#react-navigation/core: 3.7.6
Please help. Am I missing something obvious . I have list of Videos and I want to pause the currently playing video when navigating away from the same. I guess this is because of the version of react navigation I am using .In case more details are required please let me know.

React Context API & Lifecycle methods - How to use together

I'm struggling to understand how to proceed with a small React app I am making.
I have a budget tracker, where you can add costs (mortgage, bills etc.) and they have a cost value. Each time you add, edit or delete one of these, I want the global state to change, which is stored in a context.
I basically have a 'remaining balance' value, that I want to recalculate each time something changes.
I figured I'd use a life cycle method or useEffect, but when I use that in my App.js (so that it watches for changes in all subcomponents), I can't get it to work, because the life cycle method is calling a method from my Context, but because it's not wrapped in the provider, it can't access the method in the Context.
Is this a common problem and is there are recommended way to fix it? I can't seem to find a similar problem on the GoOgLe.
App.js:
import React, { useState, useContext, useEffect } from "react";
import "./css/main.css";
import Header from "./layout/Header";
import BudgetInfo from "./components/BudgetInfo";
import PaymentForm from "./components/PaymentForm";
import CostToolbar from "./components/CostToolbar";
import Costs from "./components/Costs";
import BudgetContext from "./context/budgetContext";
import BudgetState from "./context/BudgetState";
const App = () => {
const budgetContext = useContext(BudgetContext);
const { updateBalance } = budgetContext;
useEffect(() => {
updateBalance();
});
return (
<BudgetState>
<Header darkModeToggle={toggleDarkMode} />
<main
className={"main-content" + (darkMode.darkMode ? " dm-active" : "")}
>
<div className="wrap content-wrap">
<BudgetInfo />
<PaymentForm />
<CostToolbar />
<Costs />
</div>
</main>
</BudgetState>
);
};
export default App;
You need to wrap the App component. Try the simple example.
import React, { useEffect, useContext } from 'react';
import ThemeContext from './../context/context';
const Sample = () => {
const context = useContext(ThemeContext);
useEffect(() => {
console.log(context,'--')
},[])
return(
<ThemeContext.Consumer>
{color => (
<p style={{ color }}>
Hello World
</p>
)}
</ThemeContext.Consumer>
)
}
export default Sample;

Categories