Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

uncle blog posted:

Are there any obvious shortcomings with this method, or simply a way better way of doing it I should know of?

It's probably not best practice to use top-level/module-scoped variables like that in React. Those variables will be shared by every instance of your component and will persist between renders and mounts/unmounts. And changes to their values also won't trigger re-renders of your component.

You also probably don't want to use useEffect in this instance. I think a useMemo would probably be more appropriate, since your intent is to calculate some value based on another value from your context and there's no benefit delaying that calculation until after the render, which is what a useEffect will do.

What I'd recommend is splitting this permission calculation behavior out into a re-usable hook function that you can call from each page with minimal duplication of code.

JavaScript code:
const usePagePermissions = (pageName, args) => {
  const { userRole } = useContext(AppContext);

  const perms = userRole[pageName] || {};

  return useMemo(() => {
    return Object.fromEntries(
      Object.entries(perms).map((acc, [key, value]) => {
        if (typeof value === 'function') {
          return [key, value(...args)];
        } else {
          return [key, value];
        }
      }, []);
    );
  }, [perms, ...args]);
};


const CarPage = () => {
  const { canCreate, canDelete, canEdit, canRead } = usePagePermissions('carPage', [userDistrict, carDistrict]);
  // ...

Ima Computer fucked around with this message at 16:23 on Oct 6, 2020

Adbot
ADBOT LOVES YOU

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Extend from eslint-config-prettier and add additional rules to taste.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
react-hook-form is a nice option if you like pure hooks without any bespoke components

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
I can't bring myself to enjoy tailwind, even with nice helper libraries for using it with React. It gives me bad build-your-own-bootstrap vibes. Utility classes have their place, but going all-in on them feels bad. My favorite ways to do styles lately, at least in React projects, has been with theme-scale object-oriented libraries like Styled System/Theme UI. Stitches is looking like a strong up-and-coming contender too.

For most small projects though, the simplest solution is to write plain CSS. Maybe add SCSS/SASS if you want the convenience of nesting or the power of functions/mixins. If you follow some sane class-naming convention, like BEM, and enforce consistency by making extensive use of native CSS variables/custom properties (yes, all the modern browsers support this!), it's really hard to mess up.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
I'll just leave this indoctrination video for Stitches here (because I'm really jazzed about it, unlike Tailwind)

https://www.youtube.com/watch?v=Gw28VgyKGkw&t=1470s

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Empress Brosephine posted:

What's the deal with SVGs? Every once in a while I'll see a logo thats entirely SVG and i'm impressed, but I can't see how a 100+ line SVG code logo is more optimized / better than a 20kb png?

SVG's are vector graphics, so they can be scaled to any size or DPI without quality loss. Also, you can style them with CSS.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Grump posted:

sorry i have another question. looking for some
opinions: say theoretically you're making an sdk and you want to include a sample app in the repo to test that the sdk works.
...
I think lerna or yarn-workspaces is over-kill if all you want to do is include an example app.

Put your SDK in the root directory. Nest your example project in a example/ subdirectory.

Inside the example directory, include a package.json with a file dependency pointing at the parent directory:

code:
"dependencies": {
  "your-sdk-package-name": "file:.."
}

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Grump posted:

And if my example app is using webpack dev server, will it still hot reload this way if changes happen in the package.json dependency location?
I forget how it works, but I think it only depends on your webpack configuration. You might need to add an exclusion to your watchOptions in order for it to watch for changes on the symlinked folder to your SDK inside node_modules.

If your SDK has a build step, you'll need to rebuild it in order for the example project to pick up the changes.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Grump posted:

Would you guys consider it bad practice to import/export closure functions?
If you're initializing multiple instances (not just once in in init.js), then what you have there makes sense to me. There's no problem with exporting an instance if it's what you need.

If you're only initializing it once, you probably don't need a closure, nor your init.js, and can just leave interceptor as a local variable in module scope and export setNewToken directly.

Since you mentioned intercepting HTTP requests, are you using any http framework, like express/koa/hapi/fastify/etc? Those have their own established patterns for adding middleware to an HTTP server.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Stop reading outdated medium articles and start reading the documentation.

The automatic eslint config option in webstorm has literally the same behavior as the vscode eslint extension out of the box: it looks for an eslint configuration (.eslintrc or eslintConfig in package.json) in your project directory and uses it. Nothing should be behaving any differently, assuming you have an eslint config in your project.

If you don't like airbnb's rules, either overwrite the rules you don't like or don't use their config.


Here's a pretty basic, low-opinion setup for eslint w/ prettier:

Install these dev dependencies in your project: eslint prettier eslint-plugin-prettier eslint-config-prettier

Add an .eslintrc.js in the root of your project with:
JavaScript code:
module.exports = {
  env: {
    // set flags here based on the environment your JS will run in:
    // hxxps://eslint.org/docs/user-guide/configuring/language-options#specifying-environments
  },
  extends: [
    // extend the default eslint recommended config
    'eslint:recommended',
    // extend prettier plugin recommended config
    'plugin:prettier/recommended',
  ],
  rules: {
    // set or overwrite rules here, or don't, it's your config and you can do what you want
  },
};
Optionally, add a prettierrc too, if you want to set any options there.

Install the vscode eslint extension.

Optionally, add this to your vscode settings to run eslint on save:
JSON code:
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}
The only reason I'd bother with IntelliJ/WebStorm over VScode for web dev is for the customizable tab names and pretty diff viewer, neither of which are enticing enough to get me to pay the recurring license fee outside of work.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
In addition to screenreader accessibility, using semantic markup (and/or aria attributes) also ensures that your content shows up correctly in the browser's reader mode/view.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

teen phone cutie posted:

from my testing, even this will cause webpack to bundle the entirety of lodash in an app's final build :sweatdrop:
I think in order for this to be tree-shaken, you'd need to be importing from lodash-es which provides lodash as esmodules. With a CommonJS module, there's no way for webpack to guarantee that the rest of the module code doesn't have side-effects.

As for publishing your own package with tree-shaking enabled...

You should ideally build both a commonjs and esmodules version of your library, and assign their paths to main and module in your package.json

JSON code:
{
  "main": "./dist/cjs/index.js",
  "module": "./dist/esm/index.js"
}
If you have any of your library isolated into individual files, you can make those importable by adding a exports field.

JSON code:
{
  "exports": {
    "./foo": "./dist/esm/foo.js"
  }
}
(this example would make packagename/foo importable)

You'll also need to add sideEffects (a webpack-specific package.json property) with a value of false (or an array of file paths or globs of files which have side-effects)

JSON code:
{
  "sideEffects": false
}

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Fork a new copy of the repository for every candidate?

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Imagine writing ternaries or short-circuiting logical operators in JSX when you could be writing if statements using fake HTML attributes (v-if/else/else-if) that are spread out between multiple sibling elements for conditional rendering in Vue templates.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
If you're already writing Javascript code, JSX is a no-brainer. All it does is give you two new syntax features: the ability to write HTML markup and the ability to insert javascript expressions with curly braces.

Every other templating language needs to bring its own bespoke syntax for things like variable insertion, conditionals, loops/iteration, each of which comes with its own learning curve, and are things you get for free from Javascript. And (almost) all of them are abstractions of or augmentations on top of HTML syntax, which is a language that was never meant to express logic in the first place.

Vue, in particular, is really off-putting to me, because of how everything is nested inside of custom HTML attributes, including Javascript expressions. It doesn't flow well when I try to read it and it unearths repressed memories of a time when it was commonplace to see Javascript code expressed as a string in an onclick attribute.

Ima Computer fucked around with this message at 20:05 on Jun 8, 2022

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

worms butthole guy posted:

What's the best SFTP / FTP client for Windows? Mac user for many years going to Windows now

WinSCP. FileZilla is fine too.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Lumpy posted:

Those are literally the same I think, since <Star /> is just transpiled into Star() right?

It's not really the same. Using JSX syntax transpiles to:

React.createElement(Star, {}, null)

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Those look like pretty reasonable Typescript errors. I wouldn't // @ts-ignore them unless there was literally no other option to work around them.

The Merkinman posted:

code:
error TS2698: Spread types may only be created from object types.

This is saying that props.rows is not typed as an array of object types. If this type is a type you define, you should redefine it as an object type.

If not, I would try to track down what the type actually is and adjust the code accordingly. I really like this plugin (typescript explorer) which makes inspecting types in VScode a lot more ergonomic.


The Merkinman posted:

code:
error TS2722: Cannot invoke an object which is possibly 'undefined'.

This is saying that default is an optional property of slots and could be undefined.

If the types aren't lying, you probably want to optional chain it:
code:
const tabTitles = ref(slots.default?.().map((tab) => tab?.props?.title));
Or add some check to handle the undefined case before executing that line of code:
code:
if (!slots.default) {
  throw new Error('Slots default is missing!');
}
const tabTitles = ref(slots.default().map((tab) => tab?.props?.title));
I would also recommend this other VScode plugin (pretty TS errors) to make your typescript errors more readable.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

You can substitute the any for Record<string, unknown> (a record of unknown values) and get a spreadable type.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

The Merkinman posted:

What's the benefit of that vs Array<any>?

An array of objects with unspecified shape:
code:
Array<Record<string, unknown>>
Versus an array of anything (numbers, strings, objects, nulls, undefineds, :iiam:):

code:
Array<any>
The former is a more constrained (but still pretty loose) type which wouldn’t trigger a complaint about the spread operator being used on it.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Not using types or putting any in your types equivalent to putting /* eslint-disabled */ on those sections of code.

It kinda defeats the purpose of having Typescript there.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
That interface looks like its just a data type.

Unless the class is going to do something with methods, you're probably better off just use a simple type to constrain the shape of your data objects without any class/constructor:

TypeScript code:
type Item = {
  id: string
  title: string
  cost: number
  quantity?: number
  target?: string
  sale?: number
}

const someItem: Item = {
  id: 'foo',
  title: 'foo',
  cost: 123
}

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Combat Pretzel posted:

Because they're being whiny about me sitting in a department doing its own development work adjacent to them, and oh what would happen if I were to quit (or break my neck)
If you get hit by a bus, the talent pool for hiring React developers is significantly larger. :shrug:

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

HaB posted:

I code kind of seat of my pants and things are constantly shifting for the first part of something new and I don’t want typescript constantly yelling at me while I’m just tryna get the idea working.

I don’t know what my types are yet, so I refuse to argue with ts over the types until I do know.

This is one of the scenarios where I actually find Typescript to be super helpful.

When code is in a fluid state and shifting around a lot or I'm making large refactors, having types there to provide guardrails makes it a hell of a lot easier to move and change the code around without causing unexpected side-effects. Every time my types change, I'm alerted by the Typescript compiler to anywhere where an old version of the type is still expected.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
The CORS header only impacts XHR/fetch requests. It doesn't prevent a your browser window from navigating to a new URL, which is what submitting a form does.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
The react-hooks eslint plugin does a naive check for the function's name because it's a lot more reasonable than actually checking the implementation of the body of the function, not because any function named "use" is a hook.

The class of errors that lint rule is intended to guard against only occurs when using react's builtin hooks. If your function doesn't use hooks, nothing will break if you conditionally call it or change the order in which its called within a render function.

What determines if a function a hook is whether or not it "hooks into" the React rendering lifecycle - and the only way to do that is with React's builtin hooks (or I guess a class component)

If you're naming a function "use____" and it's not calling any hooks, then you're misrepresenting what that function does and are going to create confusion for anyone who tries to consume it.

Ima Computer fucked around with this message at 18:14 on Dec 13, 2023

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
I haven't used it for anything yet, but I really like HTMX. It reminds me of Tailwind, except that instead of colocating styles with your markup templates, it colocates your JS code with your markup templates. Colocation gives you dead code elimination for free, and saves you from the cognitive burden of cross-referencing markup templates and their associated JS glue code.

I could see it being used to build sites that are heavily backend-driven, with limited amounts of interactivity and/or complex state management. Basically, any time when a fully-fledged frontend framework would feel like overkill. Like for building internal tooling / reporting / dashboard-y things.

Oysters Autobio posted:

It just seems like there's a ton of deadass simple use cases where bootstrap, HTMX and flask would make a solid choice on a stack but I also am worried about creating future debt that a real frontend dev would have to maintain.

If your use cases are truly simple, then I honestly wouldn't worry about creating technical debt. You won't be able to create a significant-enough mess if you're building simple features.

Just don't use bootstrap - use Tailwind with DaisyUI instead :ssh:

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Remix is owned by Shopify, which kind of is a platform as a service... if you're building an e-commerce app, that is.

They offer hosting for custom storefronts built using their Remix-based framework called Hydrogen bundled into their subscription plans.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

teen phone cutie posted:

does anyone have good sources for proving the point of "please god don't declare all your types in d.ts files?"

See this question from a discussion around updating the Typescript docs for modules and the response below it from one of the devs.

I think the only good reasons to ever hand-write a .d.ts file are:

- Declaring variables in global/window scope
- Declaring types for JS-only libraries that don't have existing types (or overriding the existing types of a library)
- Declaring modules that aren't modules (declare module '*.png')

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Wheany posted:

Removing the click handler from the label: This works, only the input event from the checkbox gets fired.

But: I have a feeling I have tried this before and in some cases clicking on the label doesn't work for whatever reason. Is there a reason this wouldn't work? Because I really don't like the triple-toggle, especially since certain toggles can cause some pretty heavy calculations to happen.

As long as your markup creates the right association between a label and an input (which yours does) clicks on the <label> don't need to be handled - only the input. Redirecting events to the target input is one of the primary features of <label> tags.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

Nolgthorn posted:

So I'm left with "redisgn what you're doing dummy make less use of state management, or duplicate data in places". Seems like there's a bit of a hole in the market for state management that works on both the server and client, due to all this server components stuff.

It's not entirely clear what you're trying to do and what problems you're having, but if you're trying to synchronize state/data between your server and client, the solution you're looking for is probably TanStack Query

Client-side state management libraries (Redux/Jotai/Zustand/et al) are not meant to manage state on the server, that's what databases are for.

Adbot
ADBOT LOVES YOU

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

pentium166 posted:

I've been poking at React as a learning experience recently, rewriting a small Vue 3 app I built (itself a recreation of a small internal Rails app I made at my last job), and all I have learned is that I hate React and its routing/state management ecosystem and wish literally anything else had won the frontend wars

And then people decided to run this cursed abomination on the backend as well!
Do you have any substantive complaints? Which routing and state management solutions did you explore?

Yeah, it kind of sucks React doesn't prescribe a single way of doing global state management or routing and you're forced to make a choice from a multitude of satisfactory options. But "cursed"?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply